Clarify the occasion in a hurry to eliminate implementation inheritance and interface programming for the two major problems that is not an easy task, especially given the level of awareness of their own. Frankly, this is a "same old stuff," the article, but "left-" and indeed bad speculation. Therefore, after reading this article, you have to critically accept (reject) my point of view, although my view is the view from the others.
Inheritance is a very important object-oriented concepts. If you take into account the Java language features, inheritance is divided into two types: interface inheritance and implementation inheritance. This is only technical issues, even if the C + + interface does not exist in the concept, but it's actually the equivalent of virtual base class interfaces. For OO beginners, they hope their program when a large inheritance, because it looks OO. But the abuse of inheritance is a lot of problems, though sometimes we have to use inheritance to solve the problem.
Compared with interface inheritance, implementation inheritance issues to be more, it will bring more coupling. But interface inheritance is in question, which is inherited itself. Many of the issues for implementation inheritance to achieve on its own, so here focused on achieving the question of succession.
For example (in this case it's old). I want to implement a Stack class, I assume, to select Stack class inherits from ArrayList class (you can also think I would like to OO nature of laziness or for some); now has a new requirement, need to implement a thread-safe Stack , I defined a ConcurrentStack class inherits from Stack and Stack covers the portion of the code.
Because Stack inherited from ArrayList, Stack had outside exposed to all the public methods of ArrayList, even if some of the methods which it may be unnecessary; even worse, some of these methods may alter the state of Stack, The Stack and knowledge of these changes, this will cause the logic errors Stack.
If I want to add new ArrayList methods, this method is likely to undermine it, logically derived class Stack, ConcurrentStack. Therefore, the base class (parent class) Add Method (modified code), you must check whether these changes will affect the derived class; if an impact, then the derived class would have to make further changes. If the class inheritance system is not a complete person, or someone else's code to modify the case, is likely to arise because of inherited imperceptible BUG.
Issues still at stake. We sometimes see such a base class, some of the ways it is an exception, which means that if the derived class to support this approach to rewrite it, or the same as the parent class throws an exception that it does not support this method call. We can also see it as a variant of the parent class is abstract, but not all sub-classes to support this method, the method does not support an exception on the way to a position. This approach is very friendly and very safe, they can only run when the "lucky catch", and many slipping through the net of the unusual method may one day suddenly, people know what to do.
Rise to the above question is very important because the base class and derived class coupling between. Base class is often made only small changes, but they had to reconstruct all the derived classes, this is the infamous "fragile base class" problem. As the relationship between classes exist, so coupling is inevitable and even necessary. But in doing OO design, in the event such as the base class and derived class relationship between the strong coupling, we will consider consider whether it must be a succession? Is there a more elegant alternative to other options?
If we must pedant, you will see a lot of books this principle: If two classes are IS-A relationship between, then the use of inheritance; if between the two classes is Has-A relationship, then use the delegated . Very often this principle is applicable, but the IS-A and not as an absolute reason to use inheritance. Sometimes in order to eliminate problems caused by coupling, using the method of appointment and other details will be better encapsulation. Succession of external and down sometimes too much information exposed in the GOF design patterns, there are many models purpose is to eliminate inheritance.
On when to use inheritance, an important principle is to determine whether the method can be shared. For example DAO, you can set common CRUD methods in an abstract DAO, the specific DAO are derived from the abstract class. Strictly speaking, the abstract and derived DAO DAO implementation does not have IS-A relationship, we just to avoid repeating the method definition and implementation of this technology to make the choice. It can be said, using the interface or abstract class is the principle that if the contents of multiple methods of derived classes with no common place, it will use the interface as the abstract; If more than one method of derived classes with a common place, it will use the abstract class as abstract. When this principle does not apply to interface inheritance, if there is interface inheritance, it will correspondingly have implementation inheritance (base class is more abstract class).
Now to talk about Interface-oriented programming. In many agile methods, for interface programming has always been masters repeatedly emphasized. Interface-oriented programming, in fact, an abstract-oriented programming, the abstract and the concrete realization of phase separation. This principle allows us to have a higher level of abstraction model, in the face of the demands of changing, Zhi Yao abstract model so the good, Xiugaidaima Jiuyao much easier. Interface-oriented programming, but do not have to mean an interface corresponds to a class, too many unnecessary interfaces may also bring more of the workload and maintenance difficulties.
Compared to inheritance, OO concepts in multi-state to be more important. An interface can be related to multiple implementation class, for the declared interface type of method parameters, class fields, Ta Men Shixian class of more than easy to extend, stable, multi-state the benefits of this Yeshi. If I were to achieve the class as a method parameter defines a method void doSomething (ArrayList list), but if the leader some day find a better use ArrayList as LinkedList, I would have to be reconstructed by the void doSomething (LinkedList list), corresponding call this method in all areas modify the parameter type (unfortunately, I could not even object to create is used ArrayList list = new ArrayList () method,
which will greatly increase the workload of my changes). If the leadership they feel better with a list stored data set is good, I will once again reconstruction method, but this time I am smarter, I will approach defined as void doSomething (Set set), a way to create object Set set = new HashSet (). But this is still not enough, if the leaders also requested the list will be set back to how to do? So I should be reconstructed by the void doSomething (Collection collection), Collection of the highest degree of abstraction, easier to replace the concrete implementation class. Set List, or even the need for natural features, I can do to solve the problem down to type conversion, although this is not safe.
Interface-oriented programming is to hide the most important values to achieve, to abstract the implementation details instead of opening up packages, package it for the Java EE in the framework of hierarchical design and design is especially important. But even when used in the programming interface, we also need to correspond to interface and implementation, which leads to the question how to create objects. Design model is created, single cases, the factory method (template method), Abstract Factory and other patterns are good solutions. Inversion of Control is now popular (also known as dependency injection) model is based on a statement to connect the abstract and implementation, which not only reduces the monotony of the factory class is also easier to unit test.
Sum up the bar. Although I tried to refute a bad advocate interface inheritance is good, but it is not absolute. Abuse of inheritance, misuse of interfaces will cause problems. Java EE developers to do a lot of friends complain about DAO, Service in the implementation of an interface method of a class, although they seem to appear to have become one of the industry's best practices. May exclude interfaces make programs more "thin" some, but "thin" and necessarily "good", need to project specific circumstances. On the inheritance and interface best practices, Tell me what you still need its own accumulated experience and summarized.
No comments:
Post a Comment