Five basic principles of Class Design

Source: Internet
Author: User
Document directory
  •  
  • (1) Single-Resposibility Principle and interface-segregation principle)
  • Single Responsibility Principle
  • Interface isolation principle
  • (2) principle of open-closed principle and principle of dependency inversion (dependecy-inversion principle)
  • Open and closed Principle
  • Dependency inversion
  • (3) liskov replacement principle (liskov-substituion principle)

We often talk about three main characteristics of object-oriented: encapsulation, inheritance, and polymorphism. The other is abstraction, inheritance, and dynamic binding.

Then there is the five major object-oriented design principles. In the end, object-oriented design is actually a class design. Without a class, it cannot be called object-oriented. of course, there is also a so-called interface in C #. It is better to understand it as a special class.

I thinkThe most difficult thing for Object-Oriented applications is class design. There are no fixed standards for some classes and there are only some reference principles. Therefore, design is not only a technical activity, but also an artistic activity.

Five basic principles of class design (or object-oriented design)

(1) Single-Resposibility Principle and interface-segregation principle)

 

Single Responsibility Principle

A class should do only one thing as much as possible. But what is one thing?

As vitegenstan says, the world can be divided into facts, while facts can be further divided into atomic facts. atomic facts (composed of objects) cannot be further divided. it is obvious that we cannot have a standard to determine what an atomic fact is. some people think that an atomic fact can be further divided, while others may think that an atomic fact cannot be divided.

Therefore, we do not expect to accurately determine what is a single task and the boundaries of a class. this is a simple understanding. by using a class name, we can imagine the possible static attributes (member variables) and dynamic attributes (member functions) of a class name ). as we usually see a term, it will be associated with the closely related nature of the term.

The most common example to reflect the single responsibility principle is undoubtedly the design of the iterator in STL.

Some people think that the separation between containers and iterators is a poor design, and they feel that the complexity is added. it is better to simply put the iterator in the container. however, many people do not think so. first, the more classes there are, the more complex they are. in addition, if the iterator is placed in the container, some internal structures of the container will be exposed, which is not in line with the encapsulation idea. there is also the scalability problem. because there are multiple requirements for container access traversal. If you isolate the iterator, you can define some special iterators without modifying the container class. in this way, no matter what strange requirements you have, as long as the corresponding iterator comes out, OK.

 

Interface isolation principle

The interface depends on the use of multiple small specialized interfaces, instead of using a large total Interface

In fact, the simple statement is similar to the previous one. in C ++, an interface is a class, so it can be said that a single responsibility principle should be embodied. C # has a special interface, which is differentiated from the class. C # does not support multi-inheritance of classes, but only inherits multi-inheritance of interfaces. so here we can understand the interface successfully to make it a smaller and more special class, and an interface may be okay as long as there are a few methods.

 

(2) principle of open-closed principle and principle of dependency inversion (dependecy-inversion principle)

 

Open and closed Principle

Open and closed means that the service is open to extensions and closed to modifications.

This sounds confusing. the so-called modification and closure is the class you designed before. Do not modify the methods in the class. For example, delete a class, delete a function, or change the form parameter table of the function.

You can add many functions without changing the existing classes and functions. it is generally implemented through inheritance and polymorphism. in this way, the parent class can be kept as is. you only need to add some new functions to the subclass.

Of course, sometimes some application changes will inevitably lead to some function implementation details in the parent class (the implementation of the details will always follow the demand changes ). therefore, the best way is to deal with abstract programming. For example, to define an abstract class, it only involves the declaration of functions, indicating which functions should be implemented. it does not involve any details. so you don't need to modify it later. only modify or add subclass inherited from this abstract class. in fact, everything is relative. abstract classes that do not involve details are less likely to be modified. In actual projects, we may have to modify abstract classes, in violation of the open and closed principle. design principles only serve as a guiding role, rather than as a constraint for us. we try to follow this principle most of the time, but if special processing is required in some special cases, we naturally don't have to worry about the principle.

Examples that reflect the open and closed principle:

A special example is the extension method in C. whether it's an existing class library that you can't modify or a class you write yourself. if you are not allowed to modify the previous code, this naturally reflects the closed principle. what should I do if I want to extend some functions for the original class? First, you may think of inheriting the classes and then adding some methods to the subclass. however, if you just want to simply add a little bit of functionality, it will be a little extravagant for the entire class. second, there are some special Sealed Classes in C #, which cannot be inherited by you at all. so a special feature in C # is called the extension method. it is where you define a static function and take the class name of the class you want to extend as a parameter. Remember to add this before. in this way, the function you define will be "Bound" to that class. it seems that the class has multiple functions, and you can call this function by instantiating this class. an interesting feature. c ++ does not have this function.

 

 

Dependency inversion

Dependency inversion is dependent on abstraction. High-level modules do not depend on underlying modules. Both of them depend on abstraction. abstraction does not depend on specifics, but on abstraction.

Is it a bit cloudified. let's take an example. If you are going to find a job after graduation, you may have to rely on a certain skill, so you will rely on C, C ++, C #, java or Matlab and other specific skills to find a job. if some enterprises recruit people according to such specific requirements, you need to master a specific programming language to recruit people. in this way, both the person you are looking for and the person you are looking for will depend on the underlying modules of the detailed programming language. in this way, the number of people looking for a job is too small, and the number of people looking for a job is too small.

However, we would like to abstract some basic ideas of specific programming languages, such as understanding operating system principles, compilation principles, and data structure algorithms. assume that the students are looking for a job based on the abstract skills, and the recruiters are also recruiting people based on the requirements of these abstract points. as a result, there is a great range of options.

In programming, if there is a Class AA and BB, And the Class AA and BB are mutually dependent, a better method is to abstract AA into A, and BB into B, in this way, A and B are mutually dependent. in addition, AA depends on a, inherits from it, and implements specific details.

The dependency inversion design can be understood in this way. Dependency is the dependency between specific details at the beginning. We need to change to the dependency between abstract classes, reducing the coupling degree. then, with an abstract class, the implementation class inherited from it also depends on it. what about inverted words? In general, we focus on the details first, and then abstract some general ideas based on the details. therefore, it is common sense that abstraction depends on details. but now it is reversed. After determining an abstract class, the implementation of those details can be abstracted as the benchmark. otherwise, you will inherit an abstract class. If you do not fully implement its method, you will not be allowed to instantiate the object.

 

 

(3) liskov replacement principle (liskov-substituion principle)

The replacement principle is that child classes must be able to replace their base classes.

It seems quite simple. You may even think this is not nonsense. the classes we usually use are subclasses that can replace the base classes. otherwise, how can polymorphism be implemented. in fact, the reason why you didn't encounter a class that violates the liskov replacement principle is that there are not many such scenarios, and the other is that the well-designed class libraries certainly won't let classes that violate the replacement principle appear. therefore, the replacement principle is not easy to understand in your actual application.

Here is a special example that violates the replacement principle:

It is the problem of square and rectangle. We know that square is a special rectangle. So we can design two classes. The square class inherits from the rectangle class.

Then there are two variables indicating the length and width respectively, and there is a formula for calculating the area. if the area calculation method is virtual, polymorphism can be realized. call the area calculation method after setting the length and width. we know that a square is of the same length and width. if the length and width are not the same, then the square area calculation formula is called. this is definitely wrong. you may ask why the length and width are different. many design ideas are designed to make it easier for you, and to make mistakes less. no matter how you use it, there will be no errors. It should be an error at the time of compilation, so that you can realize what went wrong. in the case of the above, the compiler won't let you know what went wrong.

Therefore, it is difficult for you to design a square class that inherits from a rectangle class (note that you violate the liskov replaceable principle and do not mean that the code you write will go wrong, the design is not reasonable. in fact, you may be able to run well when designing code like this. If there are no special cases, it may be that there are no bugs at all. but the unreasonable design causes some security risks)

 

 

To sum up,The object-oriented design principle is still the embodiment of the object-oriented thinking. For example,

(1) The single responsibility principle and interface isolation principle reflect the encapsulation philosophy,

(2) the principle of openness and closure reflects the encapsulation and Polymorphism of objects. The principle of dependency inversion is the embodiment of polymorphism and abstraction.
.

(3) The liskov replacement principle is a standard for Object Inheritance,

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.