I have some entity, which depending on internals, may act in two ways. For example, my Connector class can operate as a HttpConnector and as a TCPConnector. The implementation of 'connect' method differs for these two 'engine' classes. Both of them share some common methods of Connector such as "openFileToTransfer(String fileName)" and share common attributes such as "folderWithFiles" etc. I need two find the best OOP design for this problem.
1) first way is delegation. I create Connector with TCPConnectorEngine and it works. The problem is that I need to share some settings and common methods. I dont want to copy paste them of course into each of the classes. I can provide common settings via constructor, which implies coding the same attributes two times, but sharing common methods is harder. May be I can inject Connector instance in each of them, but that looks ugly. May be I can provide a BaseClass for both of my ConnectorEngines, but this looks more complicated.
2) second way is inheritance. I just inherit TCPConnector from Connector and get all I need. But I suppose the 'engine' decision fits better for my task just because it fits better logically. It is really an engine of Connector, its not different types of Connector.. but may be I am wrong?
Which way you would choose and why?
I work with Java, if it matters for the answer.
In pattern terminology, the question boils down to, how to implement a Connection interface properly:
1) Use a facade and then delegate to a strategy.
2) Or use an abstract base class and inherit with concrete implementation.
So in my opinion 2 is a good solution, only in case the internal choreography or protocol of the chil classes is quite similar and they therefore can share a lot of structure and code, which is then captured in the base class.
If the concepts used internally are quite different, I think it is better to implement different strategies, instanciate those in a facade class and delegate to the strategy instances. If you want code reuse, e.g. for the settings, I would keep this concept in a different class, e.g. ConnectionSettings and inject that to the strategy instance from the facade.
Related
First of all, I'm using Objective-C, but this doesn't matter at all.
My situation is:
I have two different scenarios. I distinguish them by a preprocessor macro like:
#ifdef USER
do some stuff for scenario 1
#else
do some stuff for scenario 2
Both scenarios works with a list of items all across the application, but the difference is the way of getting those items.
In the first one I get the items by sending a request to a server.
In the second one, I get them from the local device storage.
What I have now is the second scenario implemented. I have a singleton class that returns to me the list of items by getting them from the local storage. (like a traditional database singleton)
I want to add the other scenario. Since the items can be get from any point across the app, I want this to be a singleton too.
Does it make sense to have a singleton superclass, and then two subclasses that implement the different ways of getting the items? Singleton hierarchies sound quite strange to me.
That's not exactly hierarchy. The superclass you're mentioning is actually an interface for your 2 concrete classes, which can be singletons if you want. The interface is an abstract entity thus any instance-related term is irrelevant to it.
You're statically defining your program behavior by using preprocessor to do the scenario choice. If you stick to this approach and it fits your requirements, you don't need any design patterns. In your code just use the interface I mentioned above, which is a port to your statically instantiated data. If you want to have more flexibility (this sounds likely), you can do your scenario choice at runtime. In this case you may find the Strategy pattern useful for applying scenarios and Factory pattern for instancing.
Factory combined with Strategy.
Factory as the pattern of using another class to make your instance rather than using just a constructor. You are already doing that with your Singleton most likely.
Strategy for the ability to configure which kind of object is actually created by the factory at rutime.
I know that interfaces cannot contain method body and we can implement in another classes and can write our custom logic. But the same thing can also implement by using inheritance with classes. Then why interfaces come into picture. If we want to override any method definition we can do in inheritance of classes and can write our custom code. What is the exact purpose of interfaces?
One reason is that a class may implement multiple interfaces but only derive from a single class.
Another is, that hierarchically totally unrelated classes may implement the same interface. In statically typed languages without interfaces, one can often observe very deep inheritance hierarchies, created only because they could not simply implement an interface and had to force unrelated classes to derive. This often tends to violate the "Is a" - principle of inheritance. Such implementations also tend to drag around unused code, just because it is needed further down the inheritance tree.
tl;dr - it can be done but the results are often ugly and unmaintainable
Interfaces - The object can do this.
Class - This is how the object does this.
Also interfaces can be used to avoid the diamond problem
This is a hard one. I've read this question in forums but nobody could come up with a satisfactory answer.
Coming from a C++ background, I've been told that Java achieves multiple inheritance through interfaces. One of the main purpose of Inheritance happens to be "code reuse".
I've been trying to understand the use of interfaces through the years. I've not understood whether interfaces achieves code reuse. If yes, then how?
Please give a good code example to substantiate that.
I already understand that interfaces are :
used to specify a contract.
used to specify additional roles,
behaviors that the class plays.
used to achieve "polymorphism", (eg: A
method like addKeyListener(KeyListener e) can accept any class that
implements KeyListener as arguments(so that it becomes of type
KeyListener),even if its not in the inheritance hierarchy of
KeyListener.
But how is it useful in the case of code reuse, when I need to add the code for the concrete methods myself....I could as well omit implementing the interface.
So how does Interfaces achieve code reusability (if it does at all)?
Coming from a C++ background, I've been told that Java achieves multiple inheritance through interfaces. One of the main purpose of Inheritance happens to be "code reuse".
Well no, Java just doesn't achieve multiple inheritance. Interfaces are the closest Java can get to multiple inheritance, but it's actually not inheritance, and it doesn't yield code reuse in the same way that inheritance can.
Where it can save you some code is that you can use all the implementations in the same way, rather than having to duplicate calling code.
I've searched in here and other forums and couldn't find a good answer..
I kind of know that Extending classes isn't the best of practices. And that I should use Interfaces more. my problem is that usually I start creating Interfaces and then move to Abstract classes because there's always some functionality that I want implemented on a super class so that I don't have to replicate it in every child classes.
For instance, I have a Vehicle class and the Car and Bike child classes. a lot of functionality could be implemented on the Vehicle class, such as Move() and Stop(), so what would be the best practice to keep the architecture clean, avoid code repetition and use Interfaces instead of Inheritance?
Thanks a lot!
(if you have no idea why I'm asking this you may read this interesting article: http://www.javaworld.com/javaworld/jw-08-2003/jw-0801-toolbox.html)
Inheritance ('extending classes') imposes significant limitations on class design and I'm not sure the use of interfaces as a replacement for inheritance is the best idea since it fails the DRY test.
These days, Composition is favored over Inheritance, so you might consider this post: Prefer composition over inheritance?
Interesting question. Everyone has different approaches. But it all based on personal experience and choice.
Usually, i start with an interface, then let an abstract class inherit that interface. And implement common actions there, and let others to be implemented by who ever inherits this class.
This give few advantageous based on by experience,
1.During function calls you can pass the elements as interface type or abstract class type.
2.Common variables such as ID, Names etc can be put on abstract class.
3.Easy for maintenance. For example, if you want to implement a new interface, then just implement in the abstract quickly.
If you keep in mind fundamental difference between interfaces and classes it will make it easier to decide which one to use. The difference is that interfaces represent just a protocol (usually behavioral) between objects involved, while abstract classes represent some unfinished constructions that involve some parts (data). In car example, interface is essentially a blueprint for the generic car. And abstract class would be like prefabricated specific model car body that needs to be filled with remaining parts to get final product. Interfaces don't even have to be in Java - it will not change anything - still blueprint.
Typically you would use abstract class within your specific implementation framework to provide its consumers with some basic functionality. If you just state that you never use abstract class in favor of interface - it's plain wrong from practical standpoint. What if you need 10 implementations of the same interface with 90% of the same code. Replicate code 10 times? Ok, may be you would use abstract class here but put interface on top of it. But why would you do that if you never intend to offer your class hierarchy to external consumers?
I am using word external in very wide sense - it can be just different package in your project or remote consumer.
Ultimately, many of those things are preferences and personal experiences, but I disagree with most blanket statements like extends is evil. I also prefer not to use extra classes (interfaces or abstract) unless it is required by specific parts of the design.
Just my two cents.
Inheritance allows code reuse and substitutability, but restricts polymorphism. Composition allows code reuse but not substitutability. Interfaces allow substitutability but not code reuse.
The decision of whether to use inheritance, composition, or interfaces, boils down to a few simple principles:
If one needs both code reuse and substitutability, and the restrictions imposed on polymorphism aren't too bad, use inheritance.
If one needs code reuse, but not substitutability, use composition.
If one needs substitutability, but not code reuse, or if the restrictions inheritance would impose upon polymorphism would be worse than duplicated code, use interfaces.
If one needs substitutability and code reuse, but the restrictions imposed by polymorphism would be unacceptable, use interfaces to wrap encapsulated objects.
If one needs substitutability and code reuse, and the restrictions imposed by polymorphism would not pose any immediate problem but might be problematic for future substitutable classes, derive a model base class which implements an interface, and have those classes that can derive from it do so. Avoid using variables and parameters of the class type, though--use the interface instead. If you do that, and there is a need for a substitutable class which cannot very well derive from the model base class, the new class can implement the interface without having to inherit from the base; if desired, it may implement the interface by wrapping an encapsulated instance of a derivative of the model type.
Judgment may be required in deciding whether future substitutable classes may have difficulty deriving from a base class. I tend to think approach #5 often offers the best of all worlds, though, when substitutability is required. It's often cheaper than using interfaces alone, and not much more expensive than using inheritance alone. If there is a need for future classes which are substitutable but cannot be derived from the base, it may be necessary to convert the code to use approach #5. Using approach #5 from the get-go would avoid having to refactor the code later. (Of course, if it's never necessary to substitute a class that can't derive from the base, the extra cost--slight as it may be--may end up being unnecessary).
Agree with tofutim - in your current example, move and stop on Vehicle is reasonable.
Having read the article - I think it's using powerful language to push a point... remember - inheritance is a tool to help get a job done.
But if we go with the assumption that for whatever reasons you can't / won't use the tool in this case, you can start by breaking it down into small interfaces with helper objects and/or visitors...
For example -
Vehicle types include submarine, boat, plane, car and bike. You could break it down into interfaces...
IMoveable
+ Forward()
+ Backward()
+ Left()
+ Right()
IFloatable
+ Dock()
ISink()
+ BlowAir()
IFly()
+ Takeoff()
+ Land()
And then your classes can aggregate the plethora of interfaces you've just defined.
The problem is though that you may end up duplicating some code in the car / bike class for IMoveable.Left() and IMoveable.Right(). You could factor this into a helper method and aggregate the helper... but if you follow it to its logical conclusion, you would still end up refactoring many things back into base classes.
Inheritance and Aggregation are tools... neither of which are "evil".
Hope that helps.
Do you want an answer for your specific case, or in general? In the case you described, there is nothing wrong with using an Abstract class. It doesn't make sense use an interface when all of the clients would need to implement the exact same code for Move() and Stop().
Don't believe all you read
Many times, inheritance is not bad, in fact, for data-hiding, it may be a good idea.
Basically, only use the policy of "interfaces only" when you're making a very small tree of classes, otherwise, I promise it will be a pain. Suppose you have a Person "class" (has eat() and sleep), and there are two subclasses, Mathematician (has doProblem() ) and Engineer ( buildSomething() ), then go with interfaces. If you need something like a Car class and then 56 bazillion types of cars, then go with inheritance.
IMHO.
I think, that Interfaces sometime also evil. They could be as avoidance of multiple inheritance.
But if we compare interface with abstract class, then abstract class is always more than interface. Interface is always some aspect of the class -- some viewpoint, and not whole as a class.
So I don't think you should avoid inheritance and use iterfaces everywhere -- there should be balance.
What can be reasons to prevent a class from being inherited? (e.g. using sealed on a c# class)
Right now I can't think of any.
Because writing classes to be substitutably extended is damn hard and requires you to make accurate predictions of how future users will want to extend what you've written.
Sealing your class forces them to use composition, which is much more robust.
How about if you are not sure about the interface yet and don't want any other code depending on the present interface? [That's off the top of my head, but I'd be interested in other reasons as well!]
Edit:
A bit of googling gave the following:
http://codebetter.com/blogs/patricksmacchia/archive/2008/01/05/rambling-on-the-sealed-keyword.aspx
Quoting:
There are three reasons why a sealed class is better than an unsealed class:
Versioning: When a class is originally sealed, it can change to unsealed in the future without breaking compatibility. (…)
Performance: (…) if the JIT compiler sees a call to a virtual method using a sealed types, the JIT compiler can produce more efficient code by calling the method non-virtually.(…)
Security and Predictability: A class must protect its own state and not allow itself to ever become corrupted. When a class is unsealed, a derived class can access and manipulate the base class’s state if any data fields or methods that internally manipulate fields are accessible and not private.(…)
I want to give you this message from "Code Complete":
Inheritance - subclasses - tends to
work against the primary technical
imperative you have as a programmer,
which is to manage complexity.For the sake of controlling complexity, you should maintain a heavy bias against inheritance.
The only legitimate use of inheritance is to define a particular case of a base class like, for example, when inherit from Shape to derive Circle. To check this look at the relation in opposite direction: is a Shape a generalization of Circle? If the answer is yes then it is ok to use inheritance.
So if you have a class for which there can not be any particular cases that specialize its behavior it should be sealed.
Also due to LSP (Liskov Substitution Principle) one can use derived class where base class is expected and this is actually imposes the greatest impact from use of inheritance: code using base class may be given an inherited class and it still has to work as expected. In order to protect external code when there is no obvious need for subclasses you seal the class and its clients can rely that its behavior will not be changed. Otherwise external code needs to be explicitly designed to expect possible changes in behavior in subclasses.
A more concrete example would be Singleton pattern. You need to seal singleton to ensure one can not break the "singletonness".
This may not apply to your code, but a lot of classes within the .NET framework are sealed purposely so that no one tries to create a sub-class.
There are certain situations where the internals are complex and require certain things to be controlled very specifically so the designer decided no one should inherit the class so that no one accidentally breaks functionality by using something in the wrong way.
#jjnguy
Another user may want to re-use your code by sub-classing your class. I don't see a reason to stop this.
If they want to use the functionality of my class they can achieve that with containment, and they will have much less brittle code as a result.
Composition seems to be often overlooked; all too often people want to jump on the inheritance bandwagon. They should not! Substitutability is difficult. Default to composition; you'll thank me in the long run.
I am in agreement with jjnguy... I think the reasons to seal a class are few and far between. Quite the contrary, I have been in the situation more than once where I want to extend a class, but couldn't because it was sealed.
As a perfect example, I was recently creating a small package (Java, not C#, but same principles) to wrap functionality around the memcached tool. I wanted an interface so in tests I could mock away the memcached client API I was using, and also so we could switch clients if the need arose (there are 2 clients listed on the memcached homepage). Additionally, I wanted to have the opportunity to replace the functionality altogether if the need or desire arose (such as if the memcached servers are down for some reason, we could potentially hot swap with a local cache implementation instead).
I exposed a minimal interface to interact with the client API, and it would have been awesome to extend the client API class and then just add an implements clause with my new interface. The methods that I had in the interface that matched the actual interface would then need no further details and so I wouldn't have to explicitly implement them. However, the class was sealed, so I had to instead proxy calls to an internal reference to this class. The result: more work and a lot more code for no real good reason.
That said, I think there are potential times when you might want to make a class sealed... and the best thing I can think of is an API that you will invoke directly, but allow clients to implement. For example, a game where you can program against the game... if your classes were not sealed, then the players who are adding features could potentially exploit the API to their advantage. This is a very narrow case though, and I think any time you have full control over the codebase, there really is little if any reason to make a class sealed.
This is one reason I really like the Ruby programming language... even the core classes are open, not just to extend but to ADD AND CHANGE functionality dynamically, TO THE CLASS ITSELF! It's called monkeypatching and can be a nightmare if abused, but it's damn fun to play with!
From an object-oriented perspective, sealing a class clearly documents the author's intent without the need for comments. When I seal a class I am trying to say that this class was designed to encapsulate some specific piece of knowledge or some specific service. It was not meant to be enhanced or subclassed further.
This goes well with the Template Method design pattern. I have an interface that says "I perform this service." I then have a class that implements that interface. But, what if performing that service relies on context that the base class doesn't know about (and shouldn't know about)? What happens is that the base class provides virtual methods, which are either protected or private, and these virtual methods are the hooks for subclasses to provide the piece of information or action that the base class does not know and cannot know. Meanwhile, the base class can contain code that is common for all the child classes. These subclasses would be sealed because they are meant to accomplish that one and only one concrete implementation of the service.
Can you make the argument that these subclasses should be further subclassed to enhance them? I would say no because if that subclass couldn't get the job done in the first place then it should never have derived from the base class. If you don't like it then you have the original interface, go write your own implementation class.
Sealing these subclasses also discourages deep levels of inheritence, which works well for GUI frameworks but works poorly for business logic layers.
Because you always want to be handed a reference to the class and not to a derived one for various reasons:
i. invariants that you have in some other part of your code
ii. security
etc
Also, because it's a safe bet with regards to backward compatibility - you'll never be able to close that class for inheritance if it's release unsealed.
Or maybe you didn't have enough time to test the interface that the class exposes to be sure that you can allow others to inherit from it.
Or maybe there's no point (that you see now) in having a subclass.
Or you don't want bug reports when people try to subclass and don't manage to get all the nitty-gritty details - cut support costs.
Sometimes your class interface just isn't meant to be inheirited. The public interface just isn't virtual and while someone could override the functionality that's in place it would just be wrong. Yes in general they shouldn't override the public interface, but you can insure that they don't by making the class non-inheritable.
The example I can think of right now are customized contained classes with deep clones in .Net. If you inherit from them you lose the deep clone ability.[I'm kind of fuzzy on this example, it's been a while since I worked with IClonable] If you have a true singelton class, you probably don't want inherited forms of it around, and a data persistence layer is not normally place you want a lot of inheritance.
Not everything that's important in a class is asserted easily in code. There can be semantics and relationships present that are easily broken by inheriting and overriding methods. Overriding one method at a time is an easy way to do this. You design a class/object as a single meaningful entity and then someone comes along and thinks if a method or two were 'better' it would do no harm. That may or may not be true. Maybe you can correctly separate all methods between private and not private or virtual and not virtual but that still may not be enough. Demanding inheritance of all classes also puts a huge additional burden on the original developer to foresee all the ways an inheriting class could screw things up.
I don't know of a perfect solution. I'm sympathetic to preventing inheritance but that's also a problem because it hinders unit testing.
I exposed a minimal interface to interact with the client API, and it would have been awesome to extend the client API class and then just add an implements clause with my new interface. The methods that I had in the interface that matched the actual interface would then need no further details and so I wouldn't have to explicitly implement them. However, the class was sealed, so I had to instead proxy calls to an internal reference to this class. The result: more work and a lot more code for no real good reason.
Well, there is a reason: your code is now somewhat insulated from changes to the memcached interface.
Performance: (…) if the JIT compiler sees a call to a virtual method using a sealed types, the JIT compiler can produce more efficient code by calling the method non-virtually.(…)
That's a great reason indeed. Thus, for performance-critical classes, sealed and friends make sense.
All the other reasons I've seen mentioned so far boil down to "nobody touches my class!". If you're worried someone might misunderstand its internals, you did a poor job documenting it. You can't possibly know that there's nothing useful to add to your class, or that you already know every imaginable use case for it. Even if you're right and the other developer shouldn't have used your class to solve their problem, using a keyword isn't a great way of preventing such a mistake. Documentation is. If they ignore the documentation, their loss.
Most of answers (when abstracted) state that sealed/finalized classes are tool to protect other programmers against potential mistakes. There is a blurry line between meaningful protection and pointless restriction. But as long as programmer is the one who is expected to understand the program, I see no hardly any reasons to restrict him from reusing parts of a class. Most of you talk about classes. But it's all about objects!
In his first post, DrPizza claims that designing inheritable class means anticipating possible extensions. Do I get it right that you think that class should be inheritable only if it's likely to be extended well? Looks as if you were used to design software from the most abstract classes. Allow me a brief explanation of how do I think when designing:
Starting from the very concrete objects, I find characteristics and [thus] functionality that they have in common and I abstract it to superclass of those particular objects. This is a way to reduce code duplicity.
Unless developing some specific product such as a framework, I should care about my code, not others (virtual) code. The fact that others might find it useful to reuse my code is a nice bonus, not my primary goal. If they decide to do so, it's their responsibility to ensure validity of extensions. This applies team-wide. Up-front design is crucial to productivity.
Getting back to my idea: Your objects should primarily serve your purposes, not some possible shoulda/woulda/coulda functionality of their subtypes. Your goal is to solve given problem. Object oriented languages uses fact that many problems (or more likely their subproblems) are similar and therefore existing code can be used to accelerate further development.
Sealing a class forces people who could possibly take advantage of existing code WITHOUT ACTUALLY MODIFYING YOUR PRODUCT to reinvent the wheel. (This is a crucial idea of my thesis: Inheriting a class doesn't modify it! Which seems quite pedestrian and obvious, but it's being commonly ignored).
People are often scared that their "open" classes will be twisted to something that can not substitute its ascendants. So what? Why should you care? No tool can prevent bad programmer from creating bad software!
I'm not trying to denote inheritable classes as the ultimately correct way of designing, consider this more like an explanation of my inclination to inheritable classes. That's the beauty of programming - virtually infinite set of correct solutions, each with its own cons and pros. Your comments and arguments are welcome.
And finally, my answer to the original question: I'd finalize a class to let others know that I consider the class a leaf of the hierarchical class tree and I see absolutely no possibility that it could become a parent node. (And if anyone thinks that it actually could, then either I was wrong or they don't get me).