Some software design principles-I would like to summarize them myself and find a more comprehensive result,

Source: Internet
Author: User

This article introduces some of the principles in software design, which are learned after long-term experience. Every programmer should understand them. I believe it will be of great help to everyone in the process of software design.

Don't repeat yourself (dry) 
Dry is the simplest rule and the easiest to understand. But it may also be the most difficult to be applied (because to do so, we need to make considerable efforts in generic design, which is not an easy task ). It means that when we discover similar code in two or more places, we need to abstract their commonalities to form a unique new method, and change the existing code so that they can call this new method with some appropriate parameters.
Reference: http://en.wikipedia.org/wiki/KISS_principle

Program to an interface, not an implementation 
This is the most fundamental philosophy in the design model. It focuses on interfaces rather than implementation, instead of relying on interfaces. Interfaces are abstract and stable, while implementations are diverse. In the future, we will mention our dependency inversion principle in the object-oriented solid principle, which is another way of this principle. There is also a principle called composition over inheritance (like combination rather than inheritance), which is the design principles in the 23 classic design patterns.

Command-query separation (cqs)-command-query separation principle 
Query: When a method returns a value to respond to a problem, it has the nature of query;
Command: When a method needs to change the state of an object, it has the nature of a command;

Generally, a method may be a pure command mode, a pure query mode, or a mixture of the two. When designing an interface, if possible, try to unify the interface to ensure that the behavior of the method is strictly a command or a query. In this way, the query method does not change the object status and has no side effects, the method that changes the object state cannot return values. That is to say, if we want to ask a question, it should not affect its answer. The actual application depends on the actual situation. The clarity of semantics and the simplicity of use need to be weighed. The command and query functions are combined into a method to facilitate the customer's use, but the clarity is reduced, assertion-based programming may be difficult and a variable is required to save the query results.

In system design, many systems are also designed in this way. The query function is separated from the command function system, which is conducive to system performance and security.

Reference: http://en.wikipedia.org/wiki/Command-query_separation

You ain't gonna need it (yagni) 
In short, this principle is to consider and design only the necessary functions to avoid over-design. Only implement the functions currently required. You can add more functions later.

Do not increase complexity if necessary.
Software development is a communication game.

In the past, there was an article about over-reconstruction on this site. This example is a counterexample of this principle. The WebSphere designer said that he had over-designed the product. When designing a system, our programmers or architects will consider a lot of scalability, which leads to a lot of compromise between the architecture and design, and finally lead to project failure. This is an ironic lesson, because the project life cycle was originally expected to be extended as much as possible, but the result shortened the life cycle.

Reference: http://en.wikipedia.org/wiki/You_Ain%27t_Gonna_Need_It

Law of Demeter-meter Law 
Law of Demeter, also known as principle of least knowledge, came from a project called Demeter at Dutch University in 1987. Craig larman calls law of Demeter "not to talk to strangers ". In the "programmer's cultivation path", the chapter of the level of detail is called the "coupling solution and the dimit law ". There are some very vivid metaphors about the dimit law:
If you want your dog to run, do you say "yes" to the dog or "4" to the dog legs?
If you go to the store to buy things, will you give the money to the clerk, or will you give the wallet to the clerk for him to take?

Talking to the dog's limbs? Ask the clerk to take the money from his wallet? This sounds crazy, but it's almost strange in our code.

The following is a formal description of the dashboard:

In the book "clean code", there is a section of Apache framework that violates the details of the Code:

Final string outputdir = ctxt. getoptions (). getscratchdir (). getabsolutepath ();

Such a long string of details about other objects, detailed details, detailed details ...... Added coupling, making the code structure complex and rigid and difficult to expand and maintain.

In refactoring, there is a kind of "feature envy" (Attachment complex) in the context of the Code. The image describes a situation that violates loc. Feature envy means that an object is more interested in the content of other objects. That is to say, it always envy the members, structures, or functions of other objects and call others' things. This structure is obviously unreasonable. Our program should be "Shy ". The customer's wallet cannot be taken out just like the clerk who did not treat himself as an outsider in the previous example. The "Shy" program only talks to the nearest friend. In this case, you should adjust the structure of the program so that the object has its own envy feature, or use reasonable design patterns (such as facade and mediator ).

Reference: http://en.wikipedia.org/wiki/Principle_of_Least_Knowledge

Object-oriented s.o.l. I. d Principle 

In general, this is the five object-oriented design principles, but I think these principles can be applied to all software development.

Single Responsibility Principle (SRP)-single Responsibility Principle 

The core idea of a single responsibility principle is:One class only does one thing and completes it well. There is only one reason for its change.. The single responsibility principle can be seen as the extension of low coupling and high cohesion in the object-oriented principle. The responsibility is defined as the cause of change to improve cohesion to reduce the cause of change. Too many responsibilities may lead to more reasons for its changes. This will lead to dependency between duties and affect each other, greatly damaging their cohesion and coupling. A single responsibility usually means a single function. Therefore, do not implement too many function points for a module to ensure that the entity has only one reason for its change.

Unix/Linux is the perfect embodiment of this principle. Each program is responsible for a single task independently.
Windows is a negative example of this principle. Almost all programs are intertwined and coupled.

Open/closed principle (OCP)-principle of open/closed 

With regard to the principle of closed development, the core idea is that modules are scalable and cannot be modified. That is to say,It is open to extensions and closed to modifications.

Open to expansion means that existing code can be expanded to adapt to new situations when there are new requirements or changes.
Closed modification means that once the class is designed, its work can be completed independently without any modification to the class.

For object-oriented users, You need to rely on abstraction instead of implementation. The "Policy mode" in 23 classic design patterns is the implementation. For non-object-oriented programming, Some APIs require you to input a function that you can extend. For example, our c-language qsort () allows you to provide a "Comparator ", memory Allocation of containers in STL and various locks of multithreading in Ace. For software, browser plug-ins belong to this principle.

Liskov substitution principle (LSP)-Rishi replacement principle 

Software Engineering guru Robert C. Martin finally simplified the Li's replacement principle into one sentence: "subtypes must be substitutable for their base types ". That is, subclasses must be able to replace them with their base classes. That is, the subclass should be able to replace any location where the base class can appear, and after replacement, the code will work normally. In addition, conditions such as if/else for determining subclass types should not appear in the code. LSP is an important guarantee for codes to comply with the open and closed principles. It is precisely because the child type can be replaced that the parent type module can be expanded without modification.

In this case, it seems to be a bit systematic. I suggest you take a look at the two most classic cases of this principle-"square is not a rectangle" and "ostrich is not a bird ". Through these two cases, you will understand what Mozi xiaozi says-"Beauty, beauty, love, not beauty .... Thieves and people; evil thieves, not wicked people ." -- Although my sister is a beauty, it does not mean that I like my sister. Thieves are human beings, but they do not hate humans.This principle allows you to consider not the relationship between semantic objects, but the actual requirement environment. 

In many cases, the relationship between classes is not very clear at the initial stage of design. LSP gives us a benchmark to judge the relationship between the classes and design: do not need to inherit, and how to design inheritance relationships.

Interface segregation principle (ISP)-interface isolation principle 

The interface isolation principle refers to implementing functions in interfaces rather than classes. It is better to use multiple specialized interfaces than to use a single total interface.

For example, we use computers in different ways, such as writing, communication, watching movies, playing games, surfing the Internet, programming, computing, and data, if we declare these functions in the computer pumping class, then our netbook, PC, server, and notebook implementation class will implement all these interfaces, this is too complicated. Therefore, we can isolate these functional interfaces, such as work learning interfaces, programming and development interfaces, online entertainment interfaces, and computing and data service interfaces, computers with different functions can selectively inherit these interfaces.

This principle can improve our software development by building blocks. In terms of design, various event listener and adapter in Java have different features for software development. Different versions have different features, which are the application of this principle.

Dependency inversion principle (DIP)-Dependency inversion principle 

High-level modules should not rely on the implementation of low-level modules, but on high-level abstraction.

For example, the wall switch should not rely on the lamp switch implementation, but on an abstract standard interface of the switch. In this way, when we expand the program, our switch can also control different lights or even different appliances. That is to say, electric lights and other electrical appliances inherit and implement our standard switch interface, and our switch manufacturer does not need to care about what kind of equipment it wants to control, but only about the Standard switch standard. This is the principle of dependency inversion.

It seems that the browser does not depend on the Web server, but only on the HTTP protocol. This principle is too important. The division of labor and standardization of society are the embodiment of this design principle.

Reference: http://en.wikipedia.org/wiki/Solid_ (object-oriented_design)

Common closure principle (CCP)-common blocking Principle 
All classes in a package should be disabled for changes of the same type. A change affects a package and affects all classes in the package. A more short statement is: the modified classes should be combined (in the same package ). If you have to modify the code in the application, we want all the modifications to occur in a package (change to close) instead of in many packages. The CCP principle is to combine all classes that need to be modified for the same reason into a package. If the two classes are physically or conceptually closely related and they change together, they should belong to the same package.

The CCP extends the "close" concept of the "Open and closed" principle (OCP). When a change is required for some reason, the scope of the change must be limited to a minimum range of packages.

Reference: http://c2.com/cgi/wiki? Commonclosureprinciple

Common Reuse Principle (CRP)-principle of common Reuse 
All classes of the package are reused together. If you reuse one of the classes, you can reuse all of them. In other words, classes that are not reused together should not be combined. The CRP principle helps us decide which classes should be put in the same package. Dependency on a package depends on everything contained in the package. When a package changes and a new version is released concurrently, all users using this package must verify their work in the new package environment, even if the portion used by them has not changed. Because if the package contains unused classes, even if the user does not care whether the class is changed, the user still has to upgrade the package and re-test the original functions.

CCP benefits the system maintainers. CCP makes the package as big as possible (CCP principles include function-related classes), CRP makes the package as small as possible (CRP principles Remove unused classes ). Their starting points are different, but they do not conflict with each other.

Reference: http://c2.com/cgi/wiki? Commonreuseprinciple

Hollywood principle-Hollywood principles 
The Hollywood principle is one sentence-"Don't call us, we'll call you .". It means that Hollywood brokers don't want you to contact them, but they will contact you as needed. That is to say, all components are passive, and all components are initialized and called by the container. The component is in a container and managed by the container.

Simply put, it is the relationship between control programs by containers, rather than directly controlling program code in non-traditional implementations. This is the concept of "control reversal:

1. Do not create an object, but describe how to create an object.
2. In the code, objects and services are not directly linked, but containers are responsible for connecting them together.

The control right is transferred from the application code to the external container. The transfer of control right is called inversion.

Hollywood principles are the basic principles of IOC (inversion of control) or di (dependency injection. This principle is similar to the dependency inversion principle. It depends on interfaces rather than instances. But what this principle should solve is how to pass this instance into the calling class? You may declare it as a member. You can use constructors and function parameters. However, IOC allows you to generate the actual configuration class through the configuration file, a configuration file read by the Service iner. However, the program may become hard to read, and the program performance may also decline.

Refer:

[Url] http://en.wikipedia.org/wiki/Hollywood_Principle [/url]
[Url] http://en.wikipedia.org/wiki/Inversion_of_Control [/url]

High Cohesion & low/loose coupling &-High Cohesion, low coupling 
This principle is a classic principle of UNIX operating system design. It minimizes the coupling between modules and strives to keep a module refined.

Cohesion: the closeness of each element in a module.
Coupling: a measurement of the degree of interconnection between different modules in a software architecture

Cohesion Means reuse and independence, and coupling means that the domino effect is a whole body.

Refer:

Http://en.wikipedia.org/wiki/Coupling_ (computer_science)
[Url] http://en.wikipedia.org/wiki/Cohesion_ (computer_science) [/url]

Convention over configuration (COC)-convention is better than Configuration Principle 
Simply put, some accepted configuration methods and information are used as internal default rules. For example, in the hibernate ing file, if the specified field name is the same as the class attribute, you can basically ignore this configuration file. Your application only needs to specify information without convention, which reduces a large amount of Convention and has to spend time and energy worrying about it. Configuration files often affect development efficiency.

Rails has very few configuration files (but not none, database connection is a configuration file). rails fans claim that the development efficiency is 10 times higher than that of Java Development. This is probably the reason. Maven also uses the COC principle. When you execute the MVN-compile command, you do not need to specify where the source file is stored, and the compiled class file is not specified, this is the COC principle.

Reference: http://en.wikipedia.org/wiki/Convention_over_Configuration

Separation of concerns (SOC)-separation of concerns 
SOC is one of the most important goals of computer science. This principle is to separate the various concerns of the problem through various means in software development. If a problem can be broken down into independent and small ones, it is relatively easy to solve. The problem is too complicated. There are too many points of attention to solve the problem, while the programmer's ability is limited and he cannot focus on all aspects of the problem at the same time. Just as the programmer's memory is as limited as the computer's knowledge, the programmer's ability to solve the problem is as limited as the complexity of the problem to be solved. When we analyze the problem, if we discuss all the things together, there will be only one result-chaos.

I remember that I had a project in my previous company and discussed it for more than a year. The project was not complicated, but I didn't use Soc. All the things were mixed up, with a bunch of programmers injecting different ideas and ideas, the entire project suddenly gets out of control. Finally, a one-year project was created for three years.

There are two main methods to achieve separation of concerns: Standardization and abstraction and packaging. Standardization is to develop a set of standards so that users can abide by them and unify people's behaviors. In this way, people who use standards do not have to worry about many different implementations of others, make your program unable to cooperate with others. Java EE is a large collection of standards. Every developer only needs to focus on the standard itself and what it is doing. Just like the developer who is developing the plug-in, just focus on developing the plug-in, instead of paying attention to how the plug-in caps are produced. The plug-in and plug-in caps will be able to match with each other. It is also a good way to achieve separation of concerns by constantly packaging some part of the program with out-of-the-box aberration. Once a function is extracted and implemented, the user who uses the function does not need to care about how the function is implemented. Similarly, once a class is implemented, class users do not have to worry about how the class is implemented internally. Such concepts as components, layers, and service-oriented are all drawn and packaged at different levels, so that users do not have to worry about its internal implementation details.

To put it bluntly, it is still "High Cohesion and low coupling ".

Reference: http://sulong.me/archives/99

Design by contract (DBC)-contractual design 
The core idea of DBC is to compare the elements in the software system with each other and the "responsibility" and "obligation. This metaphor comes from a "contract" between "customer" and "supplier" in a business activity. For example:

The supplier must provide a certain product (responsibility) and he has the right to expect the customer to have paid (right ).
The customer must pay (responsibility) and have the right to get the product (right ).
Both parties must fulfill their responsibilities that are valid for all contracts, such as laws and regulations.

Similarly, if a module in programming provides a certain function, it should:

It is expected that all the customer modules that call it shall ensure certain entry conditions: This is the prior condition of the module (the customer's obligations and the rights of the supplier, in this way, it does not need to deal with situations that do not meet the prior conditions ).
This is the module's posterior condition (the supplier's obligation is clearly the customer's right ).
It is assumed at entry time and some specific attributes are maintained at Exit: Unchanged.

A contract is a formal form of these rights and obligations. We can use "three questions" to summarize DBC, and as designers, we often ask:

What does it expect?
What is it to ensure?
What does it need to maintain?

According to the description of the concept of DBC proposed by Bertrand Meyer, a method of the class has a precondition and a subsequent condition. The precondition indicates the parameter data accepted by the method, this method can be called only when the prerequisite conditions are met. The subsequent conditions are used to indicate the status of the method when the method is completed. If a method is executed, the subsequent conditions of this method are not true, then this method should not return normally.

Now, the prerequisite and subsequent conditions are applied to the inherited subclass. The subclass method should meet the following requirements:

1. the precondition is not stronger than the base class.
2. The subsequent conditions are not weaker than the base class.

In other words, when you call an object through a base class interface, you only know the base class prerequisites and subsequent conditions. Therefore, the inherited class does not require users to provide a stronger precondition than the base class method, that is, the inherited class method must accept any conditions (parameters) that can be accepted by any base class method ). Similarly, the inherited class must comply with all subsequent conditions of the base class, that is, the behavior and output of the inherited class method must not violate any constraints established by the base class, it does not confuse users with the output of inherited class methods.

In this way, we have a contract-based LSP, which is an enhancement of LSP.

Reference: http://en.wikipedia.org/wiki/Design_by_contract

Acyclic Dependencies Principle (ADP)-no-ring dependency Principle 
The dependency structure between packages must be a direct acyclic graph. That is to say, loops (Circular dependencies) are not allowed in the dependency structure ). If the package dependency forms a ring structure, how can we break this circular dependency? There are two ways to break this circular dependency: the first method is to create a new package. If A, B, and C form a loop dependency, put these common classes in a new package D. In this way, C dependency A is changed to C dependency D and a dependency D, thus breaking the circular dependency. The second method is to use the DIP (dependency inversion principle) and ISP (interface separation principle) design principles.

The Acyclic dependency principle (ADP) solves the problem of link coupling between packages. When designing a module, there cannot be circular dependencies.

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.