How to model OO scenario - oop

I recurrently run into an scenario similar to this:
A container business class that models a hierarchy.
A business class that participates in this hierarchy and is aggregated by the aforementioned class.
Let me give you an example.
A Map has Countries. Now the Map should know where each Country is, since its main responsability besides containing all countries is to know the locations and proximity of each. From this point of view, a functionality such as isNeighbour(Country A, Country B) seems like a correct addition to Map. However, each Country should also offer a method to know if a country is nearby. Say spain.isNeighbour(italy). This is indeed useful. Now, if I don't want to duplicate functionality and responsability, what approach should I take?
The current example I am working on is something for my university, each course requires other courses and also blocks the next level ones. The major is the one that contains all courses and dictates which course precedes which. Say I want to add a dependency of a course over another, e.g to take Calculus 2 you need Calculus 1... Should I go calculus.addRequired(calculus2) and then pass it to the major object, or maybe computerScience.addRequired(calculus1, calculus2)...
I don't want to have both alternatives because to me it seems it can lead to error, but at the same time I want each course to be able to answer what are its requirements. I don't really know how to distribute responsabilities correctly.

First thing is, that there is no problem calling each other.
You can have
boolean Map.isNeighbour(Country A, Country B) { return A.isNeighbour(B); }
or
boolean Country.isNeighbour(Country other) { return map.isNeighbour(this, other); }
Second seems to need reference to global map. First makes Map look like simple facade.
Second thing is that you say it is persisted. There also might be good idea to create a service, that will query DB with related parameters. This can be either Map or some repository service. This will also allow you to query with only identities of entities (eg. countryId) instead of full objects.
I believe neither of the solutions is better or worse. Only point of difference is where other developers expect the methods to be located. But when I think about it, this would mean Map will have all responsibilities of Country, thus breaking SRP, especially if it is not call-through to the country method.

I would put the isNeighbour() method into Country.
Country would contain a map of neighbours. And then the container can call this method on the country instance in question.
This way the logic is maintained by the countries, and the container simply delegates to answer the question to them.
In case of courses it is possible that Course-1 is required for Course-2 in Major-1, but not in Major-2. In this case I would introduce another class, e.g. CourseInMajor that would contain the required courses for a given course in a given Major.

Related

Method requires specific subtype but collection is of base abstract type. What is wrong?

Recently I have fallen in a situation like this. I'm generalizing the problem because I think it relates more to the structural design than the specific problem.
General problem
There is a hierarchy of classes: an abstract base class Base and some concretions D1, D2, D3 that inherit from it. The class A contains an object's collection of type Base. A requires a computation from some service-class B but B.process() method accepts only a collection of type D1. Let's say that is important because if the input collection contains any other type the value returned is just wrong.
A have an interface that allows clients to add elements to the internal collection, which is not exposed in any other way. The classes in the hierarchy can be constructed for the same clients and pass the new values to A; A have not enough context to construct them itself.
Attempts, questions and thoughts
The major concern for me was the need to determine at runtime the type of each element in the A collection, so can filter the right ones and pass to B.process(). Even if it is possible (it is in my particular problem, more later on) it just seems wrong! I think the object who contains references to the abstract base class shouldn't have to know the concrete instances it holds.
I try to:
Change the parameter type to B.process(c: Base[]) so A doesn't have to downcast the type, but it doesn't solve anything: A still needs to filter the elements or the computation will be wrong.
Pass the complete collection Base[] to B.process() but just defer the problem of selection/downcasting to B.
Put a process() method in Base so D1 can override the behavior (well known polymorphism). The problem here is that a process() returning a SomeValue type just have sense for D1.
Separate the interface that add elements so a more specific A.addD1Element(e: D1) method could allow put D1 objects in a different collection and pass that to B. It should work but also looks... don't know, weird. If method overload based on parameter type is possible at least the process won't be so cumbersome for clients of the class.
Just separate the D1 class of the hierarchy. This is a more aggressive variation of the previous one. The issue is that D1 seems related to the whole hierarchy except for the specific requirements of B.
Those were some of my thoughts on the problem.
For instance, the language used have support to check the type of an object at runtime (instanceof) and it is easy to filter the collection based on that check. But as I say my question is more related to the paradigm. What about a language, say for instance C++, where is less handy to make a check like that?
So what could be a solution to this kind of problem? What kind of refactoring or design pattern could be applied so the problem is easy to treat with or simply fades away?
This question looks related, but I believe this is more general (although I provide a more specific context). The most upvoted answer suggest to split in different collections. This is also a think i'm considering, but that forces to change A implementation every time a new type is added.
Context (problem in action)
I'm asking in a general way because it really intrigues me on that way, but I know most of the time a design can be analyzed only with the context of the particular problem it tries to solve.
The problem at hand is similar to this:
A is a class (some kind of entity, like a DDD entity) that models a sort of agreement or debt a customer incurs for a service. It has different costs including a monthly pay. Base and related classes are Payments of different types. They share a lot in common, although most of it is data (date, amount, interests, etc); but there is at least one type of payment that have different, additional information: the monthly payment (D1). Those payments need to be analyzed carefully so a different class (B) is responsible for that, using more contextual information and all the payments of that type at once. The service needs the additional data that is specific to those payments so cannot receive an abstract Payment type (at least not in that design). Other payments doesn't have the specific information MonthlyPayment does and so they cannot generates the values that business requires and B is generating (doesn't have sense in other payment types).
All payments are stored in the same collection so other methods of the class can process all payments in a generic way.
This is mostly the context. I think the design is not the best, but I fail to see a better one.
Maybe separating only MonthlyPayment (D1) in a different collection as described earlier? But it is not the only payment that requires additional processing (it is the most complex, though), so I could end with different collections for every payment type and no hierarchy at all. Right now there are four payments types and two of them requires additional, specific analysis, but more types can be added later and the issue of need to modify the implementation every time a new type is added persists.
Is this, more discrete approach of different collections by type, a better one here? The abstract base class Payment can still be used for payments that can be manipulated trough the common interface. Also I can use a layer super type or something like that to allow reutilization of common functionality (the language allows a kind of mixing as well) and stop using the base class as root from a hierarchy.
Uf. I am sorry for the length of the text. I hope it is at least readable and clear. Thank you very much in advance.

Deep class composition and the Law of Demeter

Evening. I'm having trouble finding an appropriate design pattern for some situations of deep composition. Let me present an example.
Let's say we have a class of type Corporation that has many classes of type Subsidiary that have many classes of type Department that in type contain many classes of type Unit that in turn contain many classes of type Employee.
Now, suppose the use case is to count the number of employees for each corporation. I could loop through each corpration, loop again for each subsidiary, and so on and so forth, in something that would result in a nested loop, 4 levels deep. Plus, I would be breaking the Law of Demeter by referencing my class chain several levels below, something that is so tightly couped it would break the very moment I modified my chain.
Another thing I could do is add tons (ok maybe not tons, but a few) of shortcut references. For example, a corporation could itself ALSO contain a list of Employees resulting in never having to walk through the chain to count them. This way, classes are less tightly coupled (but are they?) and the issue now becomes how to keep the Employee list synced for both the Corporation and the Unit. I could use the Observer pattern to keep them updated I suppose but I really feel something's horribly wrong with this idea or, at the very least, I'm not really using the best solution out there.
As I'm pretty sure this is an extremely common domain, could anyone be kind enough as to point me to an appropriate design pattern?
Thanks.
I don't exactly get the second question but I am answering the first question.
As the Law of Demeter states that each entity should have least
knowledge about other units
So using that principle in your design
class Corporation{
//All the stuff about corporation
//Don't ask for what's inside corporation
public int countEmployees(){
//will apply the logic needed to calculate
}
}
Better Client code with Law of Demeter:
corporationInstance.countEmployees(); //let the corporation handle how to count and not expose inner details
Without Law of Demeter
corporationInstace.getSubsidiaries().getSomethingElse()..... //exposing the inner details of class which creates a chain that is bad.
UPDATE:
Using the above stated solution you can go in as many depths as you want by creating the countEmployees() method inside Subsidiaries and in Unit as required. There is no point in breaking the encapsulation or using Observer pattern here.
Apply the Tell Don't ask principle as you have pointed in the comment yourself and delegate the responsibility of calculating the actual employees on the class that contains employees.
Department - > uses count method on subsidiaries to add their count
Subsidiaries - > uses Units to count
Unit - > Uses employees to count
Say you want to email the customer from a link or button. You might write it like customer.getSomeParticularContactInfo(addressType).sendEmail() or customer.sendEmail() which then (inside Customer) calls getSomeParticularContactInfo("primary").sendEmail().
You are on the wrong way. This breaks Single Responsibility, I mean, Customer Object doesn't need to know, how can send E-mail, Customer object is responsible only for how to provide the e-mail address belongs to the customer. So for this functionality, you need to create another Interface like Notifier and an EmailNotifier what implements Notifier. Thereafter you will call EmailNotifier.notify(customer)

OOP: How do I deal with objects that have mutual relations?

Let's say there are two classes related to each other via some relations. For example, a Student maintains a list of the Classes he takes, and each Class has a list of Students taking it. Then I am afraid of letting the Student directly being able to modify its set of Classes, because each modification would have to be followed by a similar modification of a Class's list of Students, and vice versa.
One solution is to have a class whose sole purpose is to keep track of Class-Student relations, say Registrar. But then if some method in Student requires knowledge of its Class list, the Student needs to be passed the Registrar. This seems bad. It seems Student shouldn't have access to the Registrar, where it can also access other Students. I can think of a solution, creating a class that acts as a mediator between Student and Registrar, showing the Student only what it needs to know, but this seems possibly like overkill. Another solution is to remove from Student any method that needs to access its classes and put it instead in Registrar or some other class that has access to Registrar.
The reason I'm asking is that I'm working on a chess game in Java. I'm thinking about the Piece-Cell relations and the Piece-Player relations. If in the above example it wasn't OK for a Student to have access to the Registrar, is it OK here for a Piece to have access to the Board, since a Piece needs to look around anyway to decide if a move is valid?
What's the standard practice in such cases?
If relations can be changed - classes should be decoupled as much as possible, so along with each class create an interface, do not introduce tied relations between classes.
High level of separation you can achieve using intermediate services/helpers which encapsulates logic of communication between classes, so in this case you should not inject one class to an other even both are abstracted by interfaces, basically Student does not know anything about Class, and Class does not know anything about Student. I'm not sure whether such complexity is makes sense in your case but anyway you can achieve it.
Here is you may find a useful design pattern Mediator which can encapsulate interaction logic between two decoupled entities, take a look at it.
With the mediator pattern, communication between objects is
encapsulated with a mediator object. Objects no longer communicate
directly with each other, but instead communicate through the
mediator. This reduces the dependencies between communicating objects,
thereby lowering the coupling.
What I think you have found in your pretty nice example and explanation is that OO does not solve all problems well. As long as the responsibility is well shaped and sharp, everything is fine. And as long each responsibility fits in exactly one bucket (the class), it is pretty easy to design. But here you have a tradeoff:
If I define for each responsibility a separate class, I will get a bloated design that is pretty difficult to understand (and sometimes to maintain).
If I include for each separate responsibility at least one interface, I will get more classes and interfaces than I need.
If I decide that one of the two classes is responsible for the relation as well, this one object has more knowledge than usual about the other.
And if you introduce in each case a mediator or something similar, your design will be more complex than the problem.
So perhaps you should ask the questions:
What is the likelihood that the relation between the 2 objects will change?
What is the likelihood that the relation will exist between more 1 type of objects at each end?
Is that part of the system a highly visible part, so that a lot of other parts will interface it (and therefore will be dependent on it)?
Take the simplest solution that could possibly work and start with that. As long as the solution is kept simple, it is only your code (you don't design a library for others), there are chances that you can change the design later without hassle.
So in your concrete case,
the board field should have access to the whole board XOR
the figure on the field should have the responsibility of moving XOR
there should be an object type (ChessGame?) that is responsible for the overall knowledge about moving, blocking, attacking ...
I do think that all are valid, and it depends on your special "business case" which one is the most valid.

Basic question about OOP

I often have the same trouble when I have to design my class for a web application. The requirements are :
- maintainable (no copy-paste for instance)
- layers fully separated (the business layer doesn't have to know which method of the data layer is used)
- high performance : don't load useless data.
First I have a table with all my customers and their addresses :
Code :
Customer
--Id
--Name
--Address
----City
----ZC
----Street
Now I want a table (in another page) with all my customers and the books that they bought, I have a few possibilities :
1/ I create a new class :
Code :
CustomerWithBooks
--Id
--Name
--Books[]
----ID
----name
PRO : I load only the useful data
CONS : I build my class after my UI , and there is copy-paste.
2/ I add Books[] to the first class.
PRO : Everything is in the same class, it's maintainable
CONS : I load the address for nothing. If I don't load the address I can : lazy loading, but I really don't like it, or when I use my class I have to know which method of my DAL i called, and I don't like it.
3/ I use inheritance :
Code :
ClientBase
--ID
--Name
ClientWithBooks : ClientBase
--Books[]
ClientWithAdress : ClientBase
--Address
PRO: really maintenable, and I don't load data for nothing
CONS : What do I do if in one UI I want to show the Books AND the Address ?
4/ ?? I hope there is a perfect solution
You option 1 is close to good, assuming I understand it correctly. A customer and a book are two completely different things. You want that data/functionality separate, and should not inherit from any common base class (that you have made).
As the "Con" you say: I build my class after my UI , and there is copy-paste.
A. If you mock up some UI to help clarify requirements before you settle on your design and code up classes, that's good, not bad.
B. Good arrangement of your domain objects helps eliminate copy/paste, not cause it. If you have some seemingly repetitive code within your well-arranged classes (often data access code) that's typical, don't worry. You can address with with a good data-access layer/tool, good shared logging resources, etc. Repetitive code within your classes just means you have more design improvement to do, not that having separate classes for all your domain realities is bad.
On the page where you need to deal with both customers and books, you will use customer objects and book objects, and probably a books collection object. And depending on how your db/object-model are set up, you might be dealing with other objects to get form customer to the books they bought. For example, the customers probably buy 1 or more books at the same time, and these are tied to an Order object, which has a reference to a customer. So, you'll probably go from a
Customer to an
Orders collection containing all of that customers orders to the individual
Order objects and from there to a corresponding
Books collection containing all the
Book objects that relate to that Order object.
None of these need to inherit from each other. Now, let's say getting all the books bought by a customer is something you do a lot, and you want to streamline that. You then want to have a Books collection directly off of Customer that gives you that, though the sql queries you use to get those books still goes through Orders in the db. You must start with your object model (and tables behind the scenes) reflecting reality accurately. Even if this give you seemingly many classes, it is more simple in the end. You might end up with some inheritance, you might not.
I would to avoid 2 and 3, because it locks you into a restrictive hierarchy that doesn't really meet your needs. As you point out, there could be any combination of things that you want, such as customers and their books, and maybe their address, and maybe their ordering history. Or maybe you'll want a book with it's list of customers. Since your underlying business information is not really hierarchical, you should try to avoid making your object model unnecessarily hierarchical. Otherwise, you will build in restrictions that will cause you a lot of headaches later, because you can't think of all the scenerios now.
I think you're on the right track with 1. I would say to create some basic classes for Customers and Books, and then create a CustomerBook association class that contains an instance both the customer and the book. Then you can have you methods worry about how to load the data into that list for a given scenerio.
I would stick the address into Customer, and have a separate collection of books.
Bookshelf
--Books[]
This way, a Customer doesn't have, but can have, one or more books associated to him. PHP-code example following:
class BookshelfFactory {
public static function getBookshelf(Customer $customer) {
// perform some fetching here
return $bookshelf;
}
}
You're sort of designing backwards from an OOA&D standpoint. It's normal to use data-driven design at the persistence (usually a relational database) layer. But in OOA&D it's more normal to think of the messages an object will send and receive (you model an object's methods not its members). I would think about it this way:
Customer
+getBooks():List<Book>
+getAddress():Address
I think your problem is an issue for the implementation of your data mapping layer.
You can have highly performant queries with JOINS that return you the Customers as well as their Books.
Your mapping layer maps this into the appropriate unique objects and is responsible for creating the right 1-many aggregation for your objects.
In addition you could cater for shallow loading, for display properties to save unnecessary amounts of data to be transferred where you only need a few attributes per object.

How to solve cross referencess in OOP?

I encountered this a couple of times now, and i wondered what is the OO way to solve circular references. By that i mean class A has class B as a member, and B in turn has class A as a member.
One example of this would be class Person that has Person spouse as a member.
Person jack = new Person("Jack");
Person jill = new Person("Jill");
jack.setSpouse(jill);
jill.setSpouse(jack);
Another example would be Product classes that have some Collection of other Products as a member. That collection could for example be products that people who are interested in this product might also be interested in, and we want to upkeep that list on a per-product base, not on same shared attributes (e.g. we don't want to just display all other products in the same category).
Product pc = new Product("pc");
Product monitor = new Product("monitor");
Product tv = new Product("tv");
pc.setSeeAlso({monitor, tv});
monitor.setSeeAlso({pc});
tv.setSeeAlso(null);
(these products are just for making a point, the issue is not about wether or not certain products would relate to each other)
Would this be bad design in OOP in general? Would/should all OOP languages allow this, or is it just bad practice? If it's bad practice, what would be the nicest way of solving this?
The examples you give are (to me, anyway) examples of reasonable OO design.
The cross-referencing issue you describe isn't an artifact of any design process but a real-life characteristic of the things you're representing as objects, so I don't see there's a problem.
What have you encountered that has given you the impression that this approach is bad-design?
Update 11 March:
In systems that lack garbage collection, where memory management is explicitly managed, one common approach is to require all objects to have an owner - some other object responsible for managing the lifetime of that object.
One example is Delphi's TComponent class, which provides cascading support - destroy the parent component, and all owned components are also destroyed.
If you're working on such a system, the kinds of referential loop described in this question may be considered poor design because there's no clear owner, no one object responsible for managing lifetimes.
The way that I've seen this handled in some systems is to retain the references (because they properly capture the business concerns), and to add in an explicit TransactionContext object that owns everything loaded into the business domain from the database. This context object takes care of knowing which objects need to be saved, and cleans everything up when processing is complete.
It's not a fundamental problem in OO design. An example of a time it might become a problem is in graph traversal, for instance, finding the shortest path between two objects - you could potentially get into an infinite loop. However, that's something you would have to consider on a case-by-case basis. If you know there could be cross-references in a case like that, then code some checks in to avoid infinite loops (for instance, maintaining a set of visited nodes to avoid re-visiting). But if there's no reason it could be a problem (such as in the examples you gave in your question), then it's not bad at all to have such cross-references. And in many cases, as you've described, it's a good solution to the problem at hand.
I do not think this is an example of cross referencing.
Cross referencing usually pertains to this case:
class A
{
public void MethodA(B objectB)
{
objectB.SomeMethodInB();
}
}
class B
{
public void MethodB(A objectA)
{
objectA.SomeMethodInA();
}
}
In this case each object kind of "reaches in" to each other; A calls B, B calls A, and they become tightly coupled. This is made even worse if A and B are in different packages/namespaces/assemblies; in many cases those would create compile time errors as assemblies are compiled linearly.
The way to solve that is to have either object implement an interface with the desired method.
In your case you only have one level of "reaching in":
public Class Person
{
public void setSpouse(Person person)
{ ... }
}
I do not think this is unreasonable, nor even a case of cross-referencing/circular references.
The main time this is a problem is if it becomes too confusing to cope with, or maintain, as it can become a form of spaghetti code.
However, to touch on your examples;
See Also is perfectly valid if this is a feature you need in your code - it is a simple list of pointers (or references) to other items a user may be interested in.
Similarily it is perfectly valid to add spouse, as this is a simple real world relationship that would not be confusing to someone maintaining your code.
I have always seen it as a potential code smell, or perhaps a warning to take a step back and rationalise what I am doing.
As for some systems finding recursive relationships in your code (mentioned in a comment above), these can come up regardless of this sort of design. I have recently worked on a metadata capture system that had recursive 'types' of relationships - i.e Columns being logically related to other columns. It needs to be handled by the code trying to parse your system.
I don't think the circular references as such are a problem.
However, putting all those relationships inside objects may add too much clutter, so you may instead want to represent them externally. E.g. you might use a hash table to store relationships between products.
Referencing other objects is not a real bad OO design at all. It's the way state is managed within each object.
A good rule of thumb is the Law of Demeter. Look at this perfect paper of LoD (Paperboy and the wallet): click here
One way to fix this is to refer to other object via an id.
e.g.
Person jack = new Person(new PersonId("Jack"));
Person jill = new Person(new PersonId("Jill"));
jack.setSpouse(jill.getId());
jill.setSpouse(jack.getId());
I'm not saying it is a perfect solution, but it will prevent circular references. You are using an object instead of a object reference to model the relationship.