Core principles of general principles of Java Object Design

Source: Internet
Author: User

Since the core of object design is the class, the following principles are basically the discussion of the design of the class, the other types of elements are relatively simple, basically also conforms to most of the principles listed here. Before we have analyzed the basic principles of object design, here I will review the core principles of object Design-the solid principle. Almost all design patterns can be seen in the shadow of these principles. Single Responsibility Principle (SRP): Be a one-manThe sole responsibility principle is the single Responsibility Principle, or SRP. The definition of the SRP principle is simple:
That is, there cannot be more than one cause for class changes. Simply put, a class is responsible for only one responsibility.

Let a class be responsible for only one responsibility, if a class has more than one responsibility, it is a more fragile design. Because once a certain responsibility has changed and the code needs to be changed, other responsibilities may be changed. The so-called reaching, which is clearly what we do not want to see, so we will split this class, by two classes to maintain these two responsibilities, so that when a responsibility changes, need to change, will not affect the other duties.

Do and do only one thing, this principle applies not only to objects, but also to functions, variables and other programming elements.  Of course, in the business model, one thing to achieve the ultimate is success, I personally feel that this article is also set up.  For example, if you have an in-depth study of the idea of an iterator, it is actually the responsibility of storing data and traversing the data is separated, the collection is only responsible for the implementation of the function of storing data, and the iterator to complete the function of traversing the data. Another example I've seen: there is an auxiliary class Commonutil, which provides all the auxiliary methods that cannot be grouped into other modules, and it has the following structure:
public class commonutil{#region Canvas Helpers public void M1 () {}//... #endregion  #region screen Helpers public vo ID M2 () {}//... #endregion  #region Size Helpers public void M3 () {}//... #endregion  #region Data Helpers publi c void M4 () {}//... #endregion}

Guys, what do you think of this kind of writing?

This is put into a variety of different types of auxiliary methods, each module has an auxiliary method need to find a place to put, people are consciously found this class, so this class in each release constantly have new members to join, and eventually become a monster, use,  Look at the list of functions enough for everyone to have a bottle. My idea is, why not split into 4 small classes, each of which is dedicated to one type of accessibility? Open Closure principle (OCP): Transforming the world is not destroying the original orderThe open closure principle is the full name of open Closed Principle, or OCP, which is defined as:
Software entities should be extensible and non-modifiable. In other words, the extension is open, and the modification is closed.

This principle is at the core of all object-oriented principles.

The first goal of software design is to package change and reduce coupling, and the open closure principle is the most direct embodiment of this goal.  Other principles are more or less aimed at this goal, such as the best and right inheritance level with the Liskov substitution principle, which guarantees that the open closure principle will not be violated. The second goal of software design is reuse. This is the core power of the inheritance mechanism. Abstract and inheritance is a powerful tool for implementing open and close principles, but not the only tool, and we'll talk about another, more powerful, more flexible tool for implementing the open and closed principle: combination. word, inheritance and combination are package changes that reduce the coupling of only way。  The reasonable use of inheritance and combination is one of the standards of the level of a code farm. In the actual code, adding new functionality generally means that a new object, a good design also means that this new modification does not significantly affect existing objects. This one is the simplest to understand and the most difficult to implement.  Countless models and decoupling methods have been created to achieve this goal. Look at a classic example:
public class component{public enum status {  None,  installed,  uninstalled}  Status M_status = Status.none;  void Do () {  switch (m_status)  {case   Status.none:    Console.WriteLine ("Error ...");    break;   Case status.installed:    Console.WriteLine ("hello!");    break;   Case status.uninstalled:    Console.WriteLine ("Error ...");    break;   Default: Break;}}}  

We define a component here, the user dynamically loaded, after loading the program can be used, in order to handle the convenience, we have defined some state for the component, in different states, the component has different behavior, so there is the above code: enum definition state, function using switch implementation of the route.

   using the Switch branch is a classic practice, and the code is impeccable when there is no change in the state type of the component. However, in the actual project, after a phase, we found that the state of the component is not enough, for example, we need to deal with the behavior of the component is not configured, so we added a state in the enumeration: configured, and then add a branch in the switch.  After another phase, we found that we also had to deal with the behavior of the component when it was not initialized, so we added a state in the enumeration: Initialized, and then added a branch to the switch.  As to whether there is any further state to be needed, we are not sure yet, but it is still possible. The above behavior is a serious violation of the opening and shutting principle, this does not need to speak more. So how to improve it? use one of our most powerful tools: using inheritance or/and combining package change points。 Here we analyze, the component changes in the place is the state of the component, this is a point of change, for the point of change, for the change point, do not hesitate to seal it.
public class componentstaus{public virtual void does () {}}public class componentnone:componentstaus{public override Voi D do () {Console.WriteLine ("Error ...");}} public class componentinitialized:componentstaus{public virtual void does () {Console.WriteLine ("hello!");} public Clas s component{Componentstaus m_status = new Componentnone ();  public void Changestatus (Componentstaus newstatus) {  m_status = newstatus;}  public void Do () {  m_status. Do (); }}

In the example above, we found the change point, then abstracted a base class and put it there, and then used the inheritance mechanism to let the subclass deduce the change. When we need to add a new state configured, we just add a new subclass componentconfigured, let it inherit from Componentstaus, and rewrite the Do method. When used, it is possible to pass an instance of the subclass to component at the appropriate time (such as event handling), or it may be component to modify the state instance itself when handling the event or method.

Can you see the shadow of the opening and shutting principle? (Of course, don't be paranoid about the changes completely closed, this is impossible, just like 0 dependencies between components is not possible) Richter Replacement principle (LSP): When I grow up, I become you.The Richter replacement principle full name Liskov Substitution Principle, hereinafter referred to as LSP, is defined as:
Where any base class can appear, subclasses must be able to appear.

The LSP principle is the cornerstone of inheritance reuse, in which the base class can be reused only if the derived class is able to replace the base class, and the derived class can add new behavior based on the base class, if the functionality of the software is not affected.

The LSP principle guarantees the correct implementation of inheritance. It expects subclasses not to break the interface members of the parent class.  Once destroyed, it can be bad if the contract is broken between people.  This principle may seem easy, but it is also easy to confuse the concepts of reality with a few classic examples: rectangles and squares. In our primary school to learn mathematics, we know that the square is a special rectangle, so when writing code, the natural square class will inherit from the rectangle, the code is as follows:
public class program{static void Main (string[] args) {  Rectangle rect = new Rectangle ();  Rect.setwidth (+);  Rect.setheight (a);  Console.WriteLine (rect. Area = = * +);   Rectangle squ = new Square ();  Rect.setwidth (+);  Rect.setheight (a);  Console.WriteLine (squ. Area = = 100 * 20); }} class rectangle{public double m_width; public double m_height;  public virtual void SetWidth (double width) {m_width = width;} public virtual void SetHeight (double height) {m_height = Height } public  double area {  get {return m_width * m_height;}}} class square:rectangle{public override void Setwi DTH (double width) {  m_width = width;  M_height = width; Public  override void SetHeight (double height) {  m_width = height;  M_height = height; }}

Obviously the input is not two true, the root cause is that the square is only a long concept, and there is no rectangle of the desired width of the concept, so the rectangle defines what the square does not, that is, the rectangle should not be the base class of the square.

   when a base class appears a member of an interface that its subclasses do not want, the inheritance relationship is necessarily a lack of consideration and must be a violation of the LSP principle.。 At this point, either try to abstract the member of the base class, or the subclass chooses to inherit from the appropriate base class.  Remember this idea and we will meet again in the next principle. Besides, when I play with the rubber ducks in the children, I often wonder: Can the rubber ducks inherit from the Ducks? What do you think? Interface Separation principle (ISP): Don't eat a fat biteInterface separation principle full Name Interface segregation principle, referred to as the ISP, it is defined as:
You cannot force users to rely on interfaces that they do not use. In other words, using multiple specialized interfaces is better than using a single total interface.

This principle is closely related to the principle of single responsibility, which is consistent with the pursuit of high cohesion, but it emphasizes the high cohesion of the interface.

To see an example, we have a service interface, which is defined as:
Interface iservice{void GetUser (); void RegisterUser (); void loadproducts (); void addproduct (); void Acceptrequest (); voi D sendresponse ();}

Because it is for all clients, this interface provides all the methods that the client needs, such as user manipulation, product manipulation, data transfer operations, and a subset of the services that each client may use.

This design runs very well, the service side provides a class service implementation of this interface, and the client, it through some network services to get to this interface IService, and then directly invoke the relevant method can be. First of all, the 1th, this interface violates the single principle of responsibility, a word, " dismantled"。 2nd, each type of client handles only one object, such as a client, such as a payroll system that only handles user, and the warehouse system only processes product, and the other methods of the interface are useless to them, or a word, " dismantled"。 The following interfaces are then obtained:
Interface iuser{void GetUser (); void RegisterUser (); Interface iproduct{void loadproducts (); void Addproduct (); Interface ipeer{void Acceptrequest (); void Sendresponse (); Class Service:iuser, IProduct, Ipeer {}

In this way to get the agent object, want to process the user's client, the object will be converted to Iuser can, want to handle the conversion of the product into iproduct can.

Similarly, imagine if one day a service only provides services about the user, what will happen in the original design? dependency Inversion principle (DIP): Abstract art has vitalityDependency inversion principle full name dependence inversion Principle, referred to as dip, its definition has 3 points meaning:
1, high-level modules should not rely on the lower module, both should rely on abstraction (abstract class or interface) 2, abstract (abstract class or interface) should not rely on the details (Implementation Class) 3, the details (concrete implementation Class) should rely on the abstract

In summary, this principle says that when each class interacts with another class, try to use only abstract classes that satisfy the interface specification. Why? Because the abstract class implementation details are almost no, there is nothing to change. This article profoundly reveals the abstract vitality, abstract object is the most expressive object, because it is usually "invisible", can fill in the relevant details at any time.

Look directly at an example:
public class program{static void Main (string[] args) {  UI layer = new UI ();  Layer. Setdataaccessor (New Xmldataaccessor ());  Layer. Do (); }} class ui{dataaccessor m_accessor;  public void Setdataaccessor (Dataaccessor accessor) {m_accessor = accessor;} public void does () {  m_accessor. GetUser (); }} interface dataaccessor{void GetUser (); void RegisterUser ();} class xmldataaccessor:dataaccessor{public void GetUser () {} public void RegisterUser () {}}

The upstream component UI relies on interfaces such as Dataaccessor, rather than relying on a variety of specific subclasses, such as Xmldataaccessor, so that when you want to use other databases to store data, Just add a new class like new Databasedataaccessor, and then set it up when you set it up. This means that many people also call it " Dependency Injection ".

OK, the core principle is finished, summed up, it seems to be a sentence: " class to be simple, inherit to be cautious, change to encapsulate, abstract type to use more"。

Core principles of general principles of Java Object Design

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.