This is the first day of my participation in Gwen Challenge

Six principles of object orientation

Single responsibility principle

  • Introduction: Single responsibility Principle – SRP
  • Concept: A class should contain only a set of highly dependent functions, data encapsulation.
  • Understanding: Understanding divides a large system into a sub-module operation as far as possible, with clear division of labor and clear responsibilities.

For example,

For example, a computer system consists of a hardware system and a software system. In the computer work each system to perform their own task function, so as to realize the computer system as a whole system operation.

Through a pseudo-code to simply simulate the operation of the computer, the following implementation of the computer to perform hardware related functions, but also to perform software related functions. But from the perspective of the object-oriented, single-responsibility principle, this code can be further optimized.

class computer{
    void hardwareFunc(a){... Run hardware related functions}void softwareFunc(a){... Run software related functions}}Copy the code

The modified code looks like this, and the single responsibility principle is that each class needs to do what it suits and should do. Computer system is more as a coordination, the main control hardware and software, software code and hardware code by the respective subsystem responsible for completion.

class computer{
    Software software;
    Hardware hardware;
}

class Hardware{
    void hardwareFunc(a){... Run hardware related functions}}class Software{
    void softwareFunc(a){... Run software related functions}}Copy the code

The open closed principle

  • Open Close Principle-OCP
  • Concept: Objects in software should be open for extension and closed for modification.
  • Understanding: do not destroy the original method, through the extension method or inheritance upgrade to achieve functional perfection, the advantage is that it will not affect the old logic to avoid bugs, and can expand the object to achieve strong code.

For example,

In the following code, a System System is distinguished by type when running some code, which is very unfavorable for the later expansion. Adding the ExtraHardWare feature, for example, requires changes to the Code class and System class adaptation extensions.


class Hardware extend Code{
    Hardware(){
        type = 1;
    }
    void run1(a){... Run hardware related functions}}class Software extend Code{
    Software(){
        type = 2;
    }
    void run2(a){... Run software related functions}}class Code{
    int type;
    void run1(a){... Run software related functions}void run2(a){... Run hardware related functions}}class System{
    void start(Code code){
        if(code.type == 1){
            code.run1();
        }else if(code.type == 2){ code.run2(); }}}Copy the code

In line with the open and closed principle of Code reconstruction, Code class abstraction to achieve basic functions. When you need to extend functionality, you can easily extend it by simply adding a type that inherits Code.


class Hardware extend Code{
    void run(a){... Run hardware related functions}}class ExtraHardware extend Code{
    void run(a){... Run external hardware related functions}}class Software extend Code{
   
    void run(a){... Run software related functions}void clearCache(a){}
}

abstart Code{
    void run(a);
}

class System{
    void start(Code code){ code.run(); }}Copy the code

Richter’s substitution principle

  • Introduction: Liskov Substitution Principle — LSP
  • Concept: If for every object o1 of type S there is an object O2 of type T, such that the behavior of all programs P defined by T does not change when o1 replaces O2, then type S is a subtype of type T.
  • As long as the parent class can appear, the subclass can appear, even if the replacement of the subclass does not affect the use of, otherwise not supported. Further understanding is the use of abstraction.

For example,

The best example of this can be found in the above open close principle.

class System{
    void start(Code code){
        code.run();
    }
}

System system = new System();
Software software = new Software();
system.start(software);
Copy the code

For example, when the System class runs start, it only knows code but does not know which subclass code is, so it can only execute code’s run method in System and not Software’s clearCache method.

Dependency inversion principle

  • Dependency Inversion Principle-dip
  • Concept: Abstraction should not depend on details, details should depend on abstractions. In other words, program for the interface, not the implementation.
  • Understanding: dependencies between modules occur through abstraction. Implementation classes cannot directly depend on each other. Dependencies should be generated through interfaces or abstract classes. There is direct coupling between classes and the details of their direct dependencies, and when the implementation changes it means that the dependent needs to be modified.

For example,

As an example of the open/close principle, what if NewSystem can run Hardware as well as the System needs to run Hardware?


class Software extend Code{
   
    void run(a){... Run software related functions}void clearCache(a){}
}

abstart Code{
    void run(a);
}

class System{
    void start(Code code){ code.run(); }}Copy the code

After modification, all classes are abstracted. We don’t have to meet each other physically, we don’t rely on details, we rely on abstractions, in line with the dependency inversion principle.


class Hardware implements Code{
    void run(a){... Run hardware related functions}}class System implements BaseSystem{
    void start(Code code){ code.run(); }}class NewSystem implements BaseSystem{
    void start(Code code){ code.run(); }}interface Code{
    void run(a);
}

interface BaseSystem{
    void start(Code code);
}


void main(a){
     Code software = new Software();
     BaseSystem system1 = new NewSystem();
     system1.start(software);
     BaseSystem system2 = new System();
     system2.start(software);
}
Copy the code

Interface Isolation Principle

  • Interface Segregation Principle (ISP)
  • Concept: Clients do not rely on interfaces that are not needed.
  • Understanding: Interface systems are fragmented and decoupled, with each object only concerned with its own interfaces.

For example,

The following code combines the dependency inversion principle with the interface isolation principle. Each class only focuses on its own needs, System focuses on RUN and Thread focuses on await. Therefore, in the use of abstract interfaces by Hardware, the abstract interfaces related to the two classes are separated and defined by Code and Process respectively. So as to achieve interface isolation, selfish purpose.

class Hardware implements Code,Process{ void run(){ ... Run hardware related functions} void await(){... Class System{void start(Code Code){code.run(); } } class Thread{ void await(Code code){ code.await(); } } interface Code{ void run(); } interface Process{ void await(); } void main(){ Code software = new Software(); System system = new System(); system.start(software); Thread thread = new Thread(); thread.await(software); }Copy the code

Demeter’s rule

  • Introduction: Law of Demeter-LOD
  • Concept: A software entity should interact with as few other entities as possible.
  • Understanding: The less a class knows about the desired object coupling, the better; the caller only cares about the method that needs to be executed. The closer the relationship between classes is, the more likely it is to produce coupling, which causes great trouble for the later code maintenance.

For example,

Demeter’s rule minimizes the direct coupling between the object and the object to the maximum extent. As shown below, the direct contact between employees is separated from each other through an object as an intermediary. For later modification, the intermediary object may only be changed.

Do not conform to the Conform to the

reference

  • Design Pattern concept