Several principles before the appearance of design patterns

Source: Internet
Author: User
  • From: http://www.javaeye.com/topic/751225

    Several principles before the appearance of design patterns

    The design patterns are part of OO. The 23 gof patterns are just a few of the design patterns. Different fields will produce different design patterns. Of course, you can also summarize your own design patterns.

    For the method of learning the design pattern, we don't need to spend a long time reading them from the beginning, it only takes a dozen days and two hours every day to have a simple impression on each mode, and then apply it in actual work to read them thoroughly. In fact, as long as yourOoTo a certain extent, the design model is self-taught.

    Several important questions about learning the design model?

    Each type of design pattern is generated to solve a specific type of problem. To understand these design patterns, you must first understand what needs to drive these patterns? (That is, what problems they solve ),As long as we figure out the demand (why), we can focus more on the implementation of the demand.

    Simple class diagrams for each mode? Learning design patterns,The most important thing is to discover their benefits in practical applications, so as to deepen our understanding of the design model, we can be more in the design.OoTo improve maintainability and scalability.In order to avoid forgetting, the use of class diagrams can help us to understand the essence of a design pattern as quickly as possible. Of course, it is also a good learning method to manually create a design pattern lookup manual.

    What are the advantages of each design pattern? What are the disadvantages? Every design pattern is repeatedly summarized and refined to solve a certain type of problem. In addition to this, it also has other advantages and inevitably brings some disadvantages. Understanding these can help us know when to adopt the design model.

    Its famous application example? Many design patterns are used in java_api. We can find these patterns in them, which is good for understanding the design principles of a module.

     

    OCP (open and closed principle, extension development, and modification close)

    The OCP principle is that the design scheme can adapt to various expansion requirements without modifying the source code (of course, this is the ideal situation ). There are two ways to achieve OCP:Abstraction and encapsulation of variability.

    Abstract,JavaIt provides two ways for us: abstract classes and interfaces. For the interface, it fixes the method features of the subclass, and all sub-classes that implement it must implement specific methods, this is a convention. This Convention is an abstraction layer. We believe that the features defined by this Convention foresee any possible extensions. Therefore, such constraints cannot be changed under any circumstances, we can understand it as follows:It is disabled for modification and followsOCPThe second principle. At the same time, because sub-classes can implement interface methods in different specific forms, these different forms are sufficient to generate different behaviors for the systemThe design is open to expansion, which satisfiesOCPThe first principle.

    The encapsulation principle of variability I learned a long time ago that the design should be separated from immutable and mutable. Here I am away from the subject,Component Design (also a framework design) usually stores variability in configuration files (usually file systems, suchXML) To form a template or a process that parses the configuration file and loads the business logic into the system so that the system can run according to the business logic required by the user, despite frequent changes in business logic, we can solve this problem through a simple configuration file. We have to say that the separation of variability and non-deformation is indeed worth thinking about.Next we will return to the topic. The encapsulation of variability will drive you to find the variable factors in the system and encapsulate them. How to encapsulate it? Instead of scattering your variables in many corners of the Code, it should be encapsulated into a class. The specific manifestation of the same variability is mapped to the same abstract class (or interface). Imagine, we often say that the interface is like a socket, and the socket is a kind of variability. Different variability is like different colors, different sizes, and so on, these variability should be encapsulated into different subclasses. Inheritance should be seen as a method to encapsulate changes, rather than a method to generate special objects from common objects. We usually think that Phoenix is inherited from birds because Phoenix is special. In fact, Phoenix only encapsulates the variability of birds. Sparrow is also a bird. It is obviously different from the variability of Phoenix, because sparrow will never become a Phoenix.

    LSP)

    Where any base class can appear, the subclass will certainly appear (in turn not true ).

    This seems to describe an inheritance principle. Indeed, when implementing inheritance, we should try our best to consider that the Java compiler can check the syntax's support for the Rys replacement principle, however, it does not support the commercial logic LSP. Considering the famous rectangle and square, it can help us better understand the LSP principle.

    Generally, in mathematics, a square actually belongs to a rectangle. According to this kind of thinking, it is natural for a square to inherit from a rectangle. But don't forget, what is the definition of rectangle? The height of the rectangle is less than or equal to the width of the rectangle. The following is a test code for the LSP principle:

    Public void resize (rectangle R ){

    While (R. getheight () <= R. getwidth ()){

    R. setwidth (R. getwidth () + 1 );

    }

    }

    The LSP principle is not valid in this test code: When a rectangle is passed in, it means to increase the height of the rectangle until it is not greater than the width of the rectangle, if the input is a square or a rectangle subclass, imagine what the result will appear in this Code. Because the height of the square is always equal to the width of the rectangle, this loop will continue forever, until the stack overflows.

    Another example is Java. the properties in the util library inherit from hashtable, but properties is a special hashtable. It only accepts keys and values of the string type, the key and value of the super-class hashtable can accept any data type. This means that LSP is not valid between them. Therefore, this is a negative textbook, reminding us at all times when to use inheritance.

    Dependency Switching Principle (DIP)

    It depends on abstraction, not specific implementation. DIP is similar to another saying: interface-oriented programming.

    I don't know when there will be "layer", although you won't see it at a glanceXxThe software is divided into several layers, but there is a reason for such a layer. separation means that the coupling degree is reduced, and each department is responsible for it. You can think about the management system of your company. It is a pyramid model. The upper layer is the top management personnel. The commands issued by them directly affect the bottom-layer workers. The specific work content of the bottom-layer workers does not affect the top management personnel. The business logic layer cannot depend on the Implementation layer. The company's architects are responsible for the maintenance of the business logic layer.CoderThe company is responsible for the implementation layer. It is impossible for the company to rely on the Implementation Layer, not justCoderWhat's more important than the quality of architects is that this is simply a wrong logic.

    The dependency switching principle is the basic principle behind architecture design models such as COM, CORBA, JavaBean, and EJB.

    Dependent types: Zero coupling relationship (two classes do not reference each other) and specific coupling relationship (two classes directly reference the specific type of the other) abstract coupling relationship (two classes are referenced using their abstract classes or interfaces, which is the core of DIP ).

    How to Implement the dependency switching principle? The Implementation Layer depends on the abstraction layer. Therefore, all business logic must be developed at the abstraction layer. To change the implementation mode of the Implementation Layer, the abstraction layer must not be changed. Centralized Control of business logic is implemented by defining abstract classes and interfaces. Interface-Oriented Programming ensures that the business logic of the abstraction layer is not changed when the implementation layer changes the implementation mode. For interface programming, abstract classes and interfaces should be used for variable type declaration, parameter type declaration, method return type declaration, and data type conversion.

    The template method intuitively explains how to implement centralized control of business logic by defining abstract classes and interfaces. Generally, the permission to use specific methods of abstract classes is obtained by inheriting abstract classes, generally, the definition of these methods requires a uniform definition of business logic. The iteration sub-mode also achieves this. It defines the public iteration function as an interface and implements the collection class of this interface to support iteration and uses the types declared by the iteration sub-interface, in the implementation process, when the collection class changes, it can also work normally. This is called abstract coupling relationship, which only references iterative interfaces.

    Adhering to the dip principle will produce a large number of classes, most of which are abstract classes and interfaces. It is worth thinking about how to deal with this reference relationship. In addition, the dependency switching principle assumes that all specific classes will change, but this is not always the case in actual situations, which needs to be solved in actual situations.

    Interface isolation principle (ISP)

    A separate interface should be as small as possible for the client, rather than providing a large total interface.

    I always think this is very similar to the single responsibility principle. Many people tell them separately. I don't want to tell them clearly, it is better to interpret one statement to another.

    ThisIt is easy to understand, that is, the interface should be fine-grained and unitized to avoid interface pollution. The benefits of doing so are also obvious. An interface is equivalent to a commitment to the outside world. Are you willing to make more or less commitments to the outside world? Secondly, in aesthetics, This Is A pollution problem. Although aesthetics cannot be incorporated into design principles, the monks like to do everything cleanly and elegantly. It is a typical perfectionist.

    AlthoughISPIt is easy to understand, but it is often ignored. I often see a large interface in the company's code, what's even worse is that it is inherited from many unitized fine-grained interfaces, and it is often consumed by this interface to implement all its methods, which leads to the laziness of programmers: set the methods that do not need to be implemented to a vacuum state (that is, nothing is written in it).

    Defining interfaces is usually divided by responsibilities. One responsibility and one interface should not place multiple responsibilities in the same interface. The criteria for evaluation are: does your interface change for one reason? However, "responsibility" is a non-standardized term. In actual projects, 98 of 100 people may have different responsibilities (the other two have read this article ). Here are a few simple examples to illustrate the benefits of the interface isolation principle when we encounter problems.

    First,If I put two or more types of responsibilities in a large interface, if one day I find that I only need one of them, then, should we force it to implement this interface and then vacuze the responsibilities it does not care about (as mentioned above, set the methods that do not need to be implemented to a vacuum state, so it can only indicate that your interface contains too many responsibilities )?

    Second, if one day we find that one of our responsibilities has changed, do we have to endure the entire tragedy and modify this interface? For example, if you consider the mobile phone communication interface, it has operations such as dialing and hanging up the phone number, let's regard it as the responsibility of the agreement, it also has calls, responses, and so on, let's take it as our data transmission responsibilities. Our mobile phones are now 2 GB, and when we change to 3 GB, video calls are more than just voice data transmission, it also includes video data transmission. Do we have to change this interface? Think about how many classes implement this interface, and we modify these classes accordingly. If we define them as two interfaces and two responsibilities at the beginning, at this time, does it just need to modify the class that implements the data transmission interface?

    Third,If you are writingAPIComponents, you need to provide an interface to the outside world for secondary developers to use, I think, you certainly do not want to make more commitments to the outside world, then, let's turn your interface into a single responsibility.

    In general, I think one sentence is very handsome: "I am simple, so I am happy ". Simplicity, clarity, division of labor, and low granularity are not good. This statement is not only applicable to interfaces, but also to classes and Methods. Of course, the specific situation depends on the specific project. For example, consider a method to modify user information. It can be divided into user name, user password, and user according to the input type .... What is the fine granularity of this method? If there is a problem with this method, the affected functions will affect user name modification, user password modification, and so on... If you put all your modifications to user information in this method, all modifications to user information will be affected. This is not a joke. Moreover, such code is not self-explanatory, not readable, and not reusable.

    For example, I have a need to determine whether the actual type of the current device (which you can consider as a telecom device) is the same as the Network Element type configured by the current user, I believe many people will write a responseTrueOrFalseThis is not appropriate. This method has two responsibilities:1.Obtain the actual device type.2.Compare whether the current actual type is the same as the type configured by the user. Therefore, you only need to define a method to obtain the actual type of the current device, and then return it to you. You can judge it in the main program. The advantage of doing so is that if one day, I need to get the actual type of the Current Device in another place of the program, then the method you write cannot be reused, you must write another method like this.How tangled it is, so I am simple, I am happy.

    The principle is to die, people are living, and everything is appropriate.

    Synthesis/aggregation Reuse Principle (CARP)

    We recommend that you use synthesis/aggregation as much as possible, instead of inheritance relationships.

    I don't want to distinguish synthesis from aggregation.

    If you are wondering whether you should use synthesis, aggregation, or inheritance, I will give you two methods to judge: 1. use "has-a" and "is-a" to determine;

    2. Use the Li's replacement principle to judge.

    Dumit rule)

    A software entity acts as little as possible to interact with other software entities.

    1. only communicate with your direct friends; 2. do not talk to strangers. 3. each software organization has only the minimum knowledge of other units and is limited to software units closely related to the same unit.

    Imagine that if you have something that is very important now, you need to trust the relationship to do it, and your friends can help you do it, but you are a stranger to him, are you looking for it yourself? Or are you asking your friends to look for him? Presumably, all of us have a brain that will let our friends do this. If a friend finds that his friends cannot do this, he will find another friend or friend's friend, in short, this is also a coupling relationship.

     

    In my opinion, the most important thing about software is maintainability and good scalability (frequent changes in demand are the most terrible). variability is the biggest headache for any software maintenance, and some are disastrous, how to predict these problems at the beginning of the design is the most valuable. Most people think that this is dependent on the experience of the architect. I agree with this, but I think we should master how to encapsulate these problems after the problem is predicted.

    What is the encapsulation of variability?JavaIt provides us with two methods: interface and abstract class. It is a good way to place an interface or abstract class in the change. Take a look23Which design mode does not use interfaces or abstract classes? I often think that your design patterns, my design patterns, and everyone's design patterns should follow the same principle. This principle is to encapsulate different variability. In the end, it is to encapsulate the variability.

  • 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.