Consider the following general program structure:
Class A has an instance of Class B as a member variable
Class B has a collection member variable containing instances of class C
Events in class A are propagated to the C instances by A simply telling B about the event
What are the design patterns concerning instances of class C talking back to class A?
One option is instances of class C posting notifications to which class A subscribes. Another option is passing a reference to class A "down the chain" (from A to B then from B to each C). This latter option allows instances of C to talk directly to A.
If you mean design patterns literally (i.e. of the GoF variety) then these would be a few relevant options:
Command: pass a callback to the C items (directly or indirectly through B) so that when they want to talk back to A they can simply invoke this callback -- which can even have parameters
Iterator: B exposes a view of its aggregate collection directly to A; communication between A and C is then made directly
Mediator: Exposes notifications to which A and C might subscribe to; communication is done by posting events
Observer: What you already suggested as the first option
If on the other hand you really mean architectural patterns, then typical options are:
Your first option, A subscribing to C events. At first sight this doesn't look like an all-around good idea unless the event is extremely useful all the time, because it requires n objects to aggregate a pointer back to the callback which in the worst case they could even use just once.
Passing references to A is another option, but not a good one if you are going to pollute the public interface of A with methods just so that C can call back to it in very specific scenarios. It can be very effective if A already exposes a suitable interface, but be aware that you might need an adapter class between C calling back to A in order to not tightly couple C to A's interface.
A third option would be A iterating over (a view of) the collection provided by B directly and supplying callbacks to C instances; this has the advantages of being quite loosely coupled and that it will use the least amount of memory, but it might be a bit trickier to code.
Related
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.
Diamond problem is handled in some OOPS languages (eg. curl) by having the repeatedly inherited class as "shared"? I want to know how this works. Also, I want to know the role played by primary and secondary constructors in solving the diamond problem in these OOPS languages when shared strategy is used.
Suppose there are 4 classes say A,B,C and D. Let the inheritance structure is B and C inherit A and D inherits both B and C. Each class has a variable say A has a, B has b, C has c and D has d. How does the object creation happens for each class?
Citing Wikipedia at https://en.wikipedia.org/wiki/Multiple_inheritance at the Curl
bullet:
Curl allows only classes that are explicitly marked as shared to be
inherited repeatedly. Shared classes must define a secondary
constructor for each regular constructor in the class. The regular
constructor is called the first time the state for the shared class is
initialized through a subclass constructor, and the secondary
constructor will be invoked for all other subclasses.
From here, without knowing Curl and only with the quote above and this, where it is stated that
The object semantics of Curl are similar to those of Java and C++.
Given
A
/ \
B(A) C(A)
\ /
D(B,C)
I imagine (I don't know for sure) that the coder is responsible to disambiguate the problem by specifying the qualified name of the constructor to run, when invoking a parent constructor from the D(B,C) subclass.
It looks like A has to be declared shared, and when D is created, B runs a constructor that calls A (primary) constructor, C runs a constructor that calls A (secondary) constructor. The distinction between primary/secondary constructor call is automatic and transparent to the coder.
As two A constructors are invoked, two A objects are created in memory, that is the A class is shared with two different subclasses, but there is not a single "shared" A object, but two independent ones (see also virtual/nonvirtual inheritance that is somehow related (C++).)
For what I've read for several different languages, it is almost always the coder that disambiguates the diamond problem with qualification. Languages just define different or similar schemes of giving an error, or having a criteria to choose one of the multiple ambiguous definitions, like specific search order in the inheritance chain. Some other languages don't even allow multiple inheritance, but in some of these you are allowed to extend functionality by some ohter means (like interfaces).
I don't understand what "CBO-Coupling between object classes" really means. The definition I found is so short that I think I'm missing something, so it would be great if you help me with an example.
Here is the definition I found:
"The coupling between object classes is a count of the number of other classes to which it is coupled."
Thanks in advance.
Coupling between objects (CBO) is a count of the number of classes that are coupled to a particular class i.e. where the methods of one class call the methods or access the variables of the other. These calls need to be counted in both directions so the CBO of class A is the size of the set of classes that class A references and those classes that reference class A. Since this is a set - each class is counted only once even if the reference operates in both directions i.e. if A references B and B references A, B is only counted once.
This is the definition given here - www.virtualmachinery.com/sidebar3.htm
There is some more detail in the link - as well as an interesting general discussion of the Chidamber and Kemerer metrics - CBO is a part of these metrics.
Here's an example with UML that complements the other answers:
Notes:
CBO doesn't care about the direction of a dependency. D has a CBO of 1 because C depends on it, even though D depends on no other classes. B and C are similar cases.
Coupling can be via attributes (composition), associations, local variables, instanciations or injected dependencies (arguments to methods).
Coupling is when a class (A) depends (knows about, requires, uses) on another specific class(B). This means when you change a public member B that is used by A, you have to change A as well. You want low coupling between types, so that you can change classes without many side effects. Usually, coupling 'comes' together with bad encapsulation so you'll have A knowing information that should be private to B.
Some types are generic enough (like List in C#) and you can use them directly without fearing side effects. But whatever classes you define for your own app, you need to be aware that those might change. So in many situations, you are more interested in some behaviour (or attributes) of B, instead of A using the whole B. In those cases, it's better to extract an interface (to abstract the desired behaviour) and then A will know only about an abstraction, while B will implement it. This allows you to have more than one concrete implementation (useful every time you're dealing with things like databases, network, import/export etc) and A won't know about B.
Thus, A can unknowingly use any of B,C,D etc as long as they implement the interface and you can change things in B,C,D as long as this doesn't break the public contract (the interface).
While we usually want our classes to be decoupled, but cohesive (as in to work together), in many situations coupling won't really hurt you, as decoupling might require more effort than provide value. It's up to the developer to identify those situations and to make a proper decision. However, this comes with experience, so in the mean time, just try not to couple your classes too much.
I'm trying to understand whether the answer to the following question is the same in all major OOP languages; and if not, then how do those languages differ.
Suppose I have class A that defines methods act and jump; method act calls method jump. A's subclass B overrides method jump (i.e., the appropriate syntax is used to ensure that whenever jump is called, the implementation in class B is used).
I have object b of class B. I want it to behave exactly as if it was of class A. In other words, I want the jump to be performed using the implementation in A. What are my options in different languages?
For example, can I achieve this with some form of downcasting? Or perhaps by creating a proxy object that knows which methods to call?
I would want to avoid creating a brand new object of class A and carefully setting up the sharing of internal state between a and b because that's obviously not future-proof, and complicated. I would also want to avoid copying the state of b into a brand new object of class A because there might be a lot of data to copy.
UPDATE
I asked this question specifically about Python, but it seems this is impossible to achieve in Python and technically it can be done... kinda..
It appears that apart from technical feasibility, there's a strong argument against doing this from a design perspective. I'm asking about that in a separate question.
The comments reiterated: Prefer composition over inheritance.
Inheritance works well when your subclasses have well defined behavioural differences from their superclass, but you'll frequently hit a point where that model gets awkward or stops making sense. At that point, you need to reconsider your design.
Composition is usually the better solution. Delegating your object's varying behaviour to a different object (or objects) may reduce or eliminate your need for subclassing.
In your case, the behavioural differences between class A and class B could be encapsulated in the Strategy pattern. You could then change the behaviour of class A (and class B, if still required) at the instance level, simply by assigning a new strategy.
The Strategy pattern may require more code in the short run, but it's clean and maintainable. Method swizzling, monkey patching, and all those cool things that allow us to poke around in our specific language implementation are fun, but the potential for unexpected side effects is high and the code tends to be difficult to maintain.
What you are asking is completely unrelated/unsupported by OOP programming.
If you subclass an object A with class B and override its methods, when a concrete instance of B is created then all the overriden/new implementation of the base methods are associated with it (either we talk about Java or C++ with virtual tables etc).
You have instantiated object B.
Why would you expect that you could/would/should be able to call the method of the superclass if you have overriden that method?
You could call it explicitely of course e.g. by calling super inside the method, but you can not do it automatically, and casting will not help you do that either.
I can't imagine why you would want to do that.
If you need to use class A then use class A.
If you need to override its functionality then use its subclass B.
Most programming languages go to some trouble to support dynamic dispatch of virtual functions (the case of calling the overridden method jump in a subclass instead of the parent class's implementation) -- to the degree that working around it or avoiding it is difficult. In general, specialization/polymorphism is a desirable feature -- arguably a goal of OOP in the first place.
Take a look at the Wikipedia article on Virtual Functions, which gives a useful overview of the support for virtual functions in many programming languages. It will give you a place to start when considering a specific language, as well as the trade-offs to weigh when looking at a language where the programmer can control how dispatch behaves (see the section on C++, for example).
So loosely, the answer to your question is, "No, the behavior is not the same in all programming languages." Furthermore, there is no language independent solution. C++ may be your best bet if you need the behavior.
You can actually do this with Python (sort of), with some awful hacks. It requires that you implement something like the wrappers we were discussing in your first Python-specific question, but as a subclass of B. You then need to implement write-proxying as well (the wrapper object shouldn't contain any of the state normally associated with the class hierarchy, it should redirect all attribute access to the underlying instance of B.
But rather than redirecting method lookup to A and then calling the method with the wrapped instance, you'd call the method passing the wrapper object as self. This is legal because the wrapper class is a subclass of B, so the wrapper instance is an instance of the classes whose methods you're calling.
This would be very strange code, requiring you to dynamically generate classes using both IS-A and HAS-A relationships at the same time. It would probably also end up fairly fragile and have bizarre results in a lot of corner cases (you generally can't write 100% perfect wrapper classes in Python exactly because this sort of strange thing is possible).
I'm completely leaving aside weather this is a good idea or not.
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.