How to express requirements between components? - oop

I have two components, A and B.
Component B requires that A has a certain state.
I can write this as part of B's code,
or I can write this as part of A's code (and maybe add assertions to B)
What should I take into consideration when making such a decision?
Edit
In this scenario there might be several B-type components.
It's also assumed that I can't avoid this situation
Edit 2
This often happens when working with frameworks. I usually have a some sort of "global settings", and components that require those settings to be something

Possibilities:
Have A implement an interface that will B will check
Make A create B whenever it has such a state.
Generally, the first solution is used, because ALL Bs refer to A, but A doesn't actually have to know about ALL Bs (you said there were many). In theory, every object should do what it is supposed to do, ignoring anything else exists, unless its a controller object.
With the first solution, B checks what A has.
With the second solution, A becomes the controller of all Bs.
I would say that it's better to have Bs check for A on creation, but in special cases, like when A is your main controller class, it MIGHT be preferable to have A create B.
Edit as response to Edit 2 by OP
Yes, in this case it's almost always better to have B check in global settings. Global settings are there so you can check them! The only exception is if A is also the owner of all other components (such as the Game class in XNA)... Even there it would be difficult to choose and just to keep the architecture intact I'd still make B check inside of A, it's just more clean and healthy.

I'm not sure that coupling is too high (at least not from your description of the problem alone).
I think the general answer to your general question comes from the concept of ownership/responsibility that so pervades OO in general. If B needs A to be in some state before doing something, then B must make sure A is in that state before doing it. Responsibility lies with B - put the code in B.
Presumably A has its own life independent of B. Let it be A, man.

Related

What is the best way to pass certain attribute values from one object to another in OOP?

Considering a class A that instantiates from a class B. Class B requires certain values from an instance of class A. What is best-practice, in terms of the SOLID or other design principles, for passing these values from A to B:
by passing the whole instance of A to the constructor of B
by just passing the necessary attribute values from an instance of A to the constructor of B
depends on the situation?
In case of (3), which criteria would favour one or the other solution?
(I do not know if this has an effect on the possible answers, but I am coding in Python)
This is kind of an open question, and I would say it depends on the situation. Since you specifically say that B will be instantiated from A, I assume Dependency Injection (the D from SOLID) is out of the question. I would then focus on the Single-responsibility principle, in addition to the general goal of keeping code as clean as possible.
A couple of things to consider:
How many "values" will B actually require? If B only requires one or two simple values, then I would pass them in as parameters to keep it clean and simple. If it needs more than that, then you could either pass the whole of A (or a reference to it) in as a parameter, and let B pick what it needs from there, or create another class (C?) that contains exactly those values that are needed. That will keep the constructor signature of B fairly clean, and make it less burdensome to add / change the data passed into it (it will probably be easier and less messy to modify C later than to modify the signature of B, and all calls to it).
Where will B be used? If it will only ever be used by A, then it might make sense to let B fetch data directly from A as needed. If it will be used other places and by other classes, then it might be better to minimize any dependency on A, and make sure it has everything it needs from the get-go. This also applies if there is a chance B will need to be serialized and stored or sent over a network, etc., as it might then not have access to A.
The optimal solution will vary depending on context. You might for instance think of the difference between two tightly coupled classes dealing with the GUI of a Windows Desktop application, and two classes in a service architecture, where one or both might contain data to be transferred or stored in a database.
I think you missed one -- and the one that is actually most common.
You pass a reference to the whole object to B, which either holds the reference, or copies the values it needs during construction.
Depending on the relationship between the objects, either is acceptable.
Your solution #2 is common for those cases in which instantiating A does not require B -- that is, it could be instantiated by C which has equivalent values, or even just programmatically from values either input or computed at run time.
For whatever it's worth, I usually use #2, but if I commonly construct based on B, I will create a special constructor fascade that accepts B and harvests the values needed into the primary constructor.

Is it OK to compose an aggregate with immutable data from another aggregate?

If an aggregate needs some read-only data that doesn't belong to itself to performs an operation, is there any negative consequence to let the repository query some data from another aggregate to create the aggregate?
In detail:
I have a BC with two aggregates, say A and B. B needs a bit of data from A to perform some operation but won't modify it in any way. The data fits better on A since there are the rules to modify it.
Reading IDDD and PPP of DDD it seems that it is acceptable to pass a transient reference of an aggregate (or sub entity of it) to another one, or pass a read-only view as a value object to the other aggregate.
In my example, B doesn't need the whole A aggregate but only some specific data, so a value object seems like a good approach in this case. A could create the VO acting as a factory, the VO will conform to the UL and B doesn't need to be aware of A at all. A business use case in the application layer can reconstitute A and B from repositories, tell A to create the VO and performs operation on B passing VO.
Lets suppose now that reconstitution of A is expensive or there is another reason for what is not desirable to load the whole A to create the VO with just a bit of information (maybe the data is not from one instance of A but is aggregated from a list of them or whatever). Here a simple solution could be let the repository of A create the VO directly from the data store. I feel comfortable with this and seems it is a common pattern.
But now I'm thinking in a case when the operation on B is performed many times, or maybe is part of a bigger calculation on B that many other operations need. I could have a reference to the VO with the data needed (as a private, read-only property of B or somewhere in its graph) and let the repository of B take the data needed to create the VO and reconstitute B with it. Now B will always have the data locally to performs its operations. The data taken from A cannot be modified; saving B through its repository will just discard that data (maybe it could use it to detect a conflicting concurrent update), A and B will not be consistent at all times but that's OK, and reload B from repository will query the data again to update the view inside B in case of a conflict.
This approach seems OK to me since, as I understand, the domain model is unrelated to the data model, with the repository acting as a sort of ACL between the two. Also there is a single source of truth for the data inside A since the copy inside B is immutable and eventually consistent. The drawbacks I see are that repository will have more logic (but not business logic) and that it could be unclear where exactly the data is coming from since the dependency from B to A is now hidden inside infrastructural code.
So the questions are:
Is this a not-so-good approach after all?
Is there another drawback I am not seeing?
Did you or someone do something like this so I can learn from that experience?
I know the example is very poor since in DDD everything is about context. But this is a question I came up many times in different situations. I know as well that a valid concern is if aggregate boundaries are well defined, but let say they look good for the problem at hand.
is it acceptable to let the repository query some data from another aggregate to create the aggregate?
Acceptable is kind of weakly defined. A better question to ask might be "are there negative consequences?"
In this example, the usual consideration is whether or not the system becomes harder to change. Take a look at Adam Ralph's talk on service boundaries to get a sense for what happens when you don't control the coupling between components.
These days, if B needs a copy of A's data, then we usually introduce into our design of B a cache of A's data. Store the copy of the data with B, and work out explicitly how and when updates to A are communicated to B. The cache becomes part of B's data model.
See also Pat Helland's paper: Data on the Outside versus Data on the Inside..

Issues with the Open/Closed Principle?

Was reading up on the Open/Closed principle of SOLID design and was curious about it's maintainability.
Lets say I have child class B and C which inherit from parent class A. B has methods unique to B, C has methods unique to C. Parent class A has two common methods that are utilized by the child classes.
In a future code release, let's say we have a new feature that introduces a common method between classes B and C. We now cannot push that method up to class A because it'd violate the "Closed for modification" portion of the principle. This seems to introduce code redundancy. Not only that, but technically wouldn't adding this new feature to classes B and C be also violate the modification tenet of the principle?
It seems with the Open/Closed approach you end up building an unnecessary, cascading hierarchy of child classes simply because one is not allowed to make alterations to the original code. Is this a correct assumption/understanding?
You don't have a crystal ball, you can't see the future and predict that a change request will happen.
However once a change request has been made, it is much more likely another change in that area will come later.
Lets take your cars example from the comment: The moment that the change request for all cars to now honk is received you should be considering if another such change will come in later. Assuming you decide it's a good chance that it will, there's only one thing for it, that's to refactor to make this whole situation Open for extension and Closed for modification. So that it's not only easy to add honking now, but you can add the next such feature with ease.
You are correct that to do apply this prematurely can bloat code and it will also receive plenty of YAGNI comments during code reviews.
It seems with the Open/Closed approach you end up building an
unnecessary, cascading hierarchy of child classes simply because one
is not allowed to make alterations to the original code. Is this a
correct assumption/understanding?
No I don't think following the open/closed principle results in cascading hierarchies of child classes.
Firstly, it's just a principle or goal. There might be times when adding a method to a base class is clearly the "right" approach even for SOLID devotees.
Secondly, a lot of methods in a base class (clearly resulting in changes) is a bit of a code smell to start with. Have you looked into the phrase "favour composition over inheritance"?

Expand object oriented code

Are there any tools that will expand object oriented code so there is no sharing of any kind? For example if I have two classes A and B which inherit C then the tool would adjust classes A and B to no longer use C. It would also be nice if the tool did this and it still compiled and produced the same results. I think the main difficulty would be adjusting any conditional logic if class type is checked dynamically.
I know this is totally pointless from a machine perspective, but it would be a fun academic exercise.
While there are various refactoring tools out there, I doubt your question has practical application as it would require substantial contextual knowledge and human intervention to perform that kind of automatic manipulation.
In your example, it's not just enough that A and B obtain C's methods and properties, but the fact that in many cases, there are places where you want to hand A (or B) to a method and have it treated like a C. Or, you might want to hand it to something that takes a C, but have A's (or B's) specific behavior invoked --- imagine a collection that invokes .DoThing() on whatever object is inside of it.
You'd have to not only bust apart the classes, but have all kind of other overloaded functions with lots of redundant looking code (especially for the types, not just the behaviors).
I'd say while an interesting thought experiment, perhaps we should place it in the bad idea pile. I doubt it would help for readability, extensibility, or performance.
The problem with this is that code which uses C rather than A or B is hard to deal with:
public void workWithSomeC( C useThis ) { ... }
in our OO code we can pass either an A or a B to that function. Can't do that if A and B no longer have anything in common.
I would think by duplicating such code something could be made to work, but good grief what a horrible idea ;-)

Act on base or subclass without RTTI or base class modification

I asked a similar question yesterday that was specific to a technology, but now I find myself wondering about the topic in the broad sense.
For simplicity's sake, we have two classes, A and B, where B is derived from A. B truly "is a" A, and all of the routines defined in A have the same meaning in B.
Let's say we want to display a list of As, some of which are actually Bs. As we traverse our list of As, if the current object is actually a B, we want to display some of Bs additional properties....or maybe we just want to color the Bs differently, but neither A nor B have any notion of "color" or "display stuff".
Solutions:
Make the A class semi-aware of B by basically including a method called isB() in A that returns false. B will override the method and return true. Display code would have a check like: if (currentA.isB()) B b = currentA;
Provide a display() method in A that B can override.... but then we start merging the UI and the model. I won't consider this unless there is some cool trick I'm not seeing.
Use instanceof to check if the current A object to be displayed is really a B.
Just add all the junk from B to A, even though it doesn't apply to A. Basically just contain a B (that does not inherit from A) in A and set it to null until it applies. This is somewhat attractive. This is similar to #1 I guess w/ composition over inheritance.
It seems like this particular problem should come up from time to time and have an obvious solution.
So I guess the question maybe really boils down to:
If I have a subclass that extends a base class by adding additional functionality (not just changing the existing behavior of the base class), am I doing something tragically wrong? It all seems to instantly fall apart as soon as we try to act on a collection of objects that may be A or B.
A variant of option 2 (or hybrid of 1 and 2) may make sense: after all, polymorphism is the standard solution to "Bs are As but need to behave differently in situation X." Agreed, a display() method would probably tie the model to the UI too closely, but presumably the different renderings you want at the UI level reflect semantic or behavioural differences at the model level. Could those be captured in a method? For example, instead of an outright getDisplayColour() method, could it be a getPriority() (for example) method, to which A and B return different values but it is still up to the UI to decide how to translate that into a colour?
Given your more general question, however, of "how can we handle additional behaviour that we can't or won't allow to be accessed polymorphically via the base class," for example if the base class isn't under our control, your options are probably option 3, the Visitor pattern or a helper class. In both cases you are effectively farming out the polymorphism to an external entity -- in option 3, the UI (e.g. the presenter or controller), which performs an instanceOf check and does different things depending on whether it's a B or not; in Visitor or the helper case, the new class. Given your example, Visitor is probably overkill (also, if you were not able/willing to change the base class to accommodate it, it wouldn't be possible to implement it I think), so I'd suggest a simple class called something like "renderer":
public abstract class Renderer {
public static Renderer Create(A obj) {
if (obj instanceOf B)
return new BRenderer();
else
return new ARenderer();
}
public abstract Color getColor();
}
// implementations of ARenderer and BRenderer per your UI logic
This encapsulates the run-time type checking and bundles the code up into reasonably well-defined classes with clear responsibilities, without the conceptual overhead of Visitor. (Per GrizzlyNyo's answer, though, if your hierarchy or function set is more complex than what you've shown here, Visitor could well be more appropriate, but many people find Visitor hard to get their heads around and I would tend to avoid it for simple situations -- but your mileage may vary.)
The answer given by itowlson covers pretty well most part of the question. I will now deal with the very last paragraph as simply as I can.
Inheritance should be implemented for reuse, for your derived class to be reused in old code, not for your class reusing parts of the base class (you can use aggregation for that).
From that standpoint, if you have a class that is to be used on new code with some new functionality, but should be used transparently as a former class, then inheritance is your solution. New code can use the new functionality and old code will seamlessly use your new objects.
While this is the general intention, there are some common pitfals, the line here is subtle and your question is about precisely that line. If you have a collection of objects of type base, that should be because those objects are meant to be used only with base's methods. They are 'bases', behave like bases.
Using techniques as 'instanceof' or downcasts (dynamic_cast<>() in C++) to detect the real runtime type is something that I would flag in a code review and only accept after having the programmer explain to great detail why any other option is worse than that solution. I would accept it, for example, in itowlson's answer under the premises that the information is not available with the given operations in base. That is, the base type does not have any method that would offer enough information for the caller to determine the color. And if it does not make sense to include such operation: besides the prepresentation color, are you going to perform any operation on the objects based on that same information? If logic depends on the real type, then the operation should be in base class to be overriden in derived classes. If that is not possible (the operation is new and only for some given subtypes) there should at least be an operation in the base to allow the caller to determine that a downcast will not fail. And then again, I would really require a sound reason for the caller code to require knowledge of the real type. Why does the user want to see it in different colors? Will the user perform different operations on each one of the types?
If you endup requiring to use code to bypass the type system, your design has a strange smell to it. Of course, never say never, but you can surely say: avoid depending on instanceof or downcasts for logic.
This looks like text book case for the Visitor design pattern (also known as "Double Dispatch").
See this answer for link to a thorough explanation on the Visitor and Composite patterns.