Python object-oriented - Six design principles

Design Principles

Open - Closed Principle (objectives, general guiding principle)

Open Closed Principle

"On" means that allows a class to the big even allows a system can be extended at any time for their function.

"Close" refers to the time allowed in the expansion and modification functions are already written to reach the underlying code (such as the parent class).

For a relatively simple example, the relationship can be understood as a computer disk and a hard disk and a U.

All will write the key code for the type of write processes together, like in the already installed to a main chassis adding a hard disk, it is first required to open the main chassis, and then tied to the data line appearance when installed split solution, selected data line is inserted on the hard disk, then the rest of the line tied again, good reseal the main chassis, time-consuming.

And if you want to have packed the main chassis plus a U-disk, U disk ready just to align USB interface access, it can, throughout the course of the main chassis already packed and there is no internal structure change; and if you want to modify or expansion of the U disk, then only need to operate U-U disk even Alternatively, the process of the main chassis is any change does not occur. In contrast, the efficiency is higher.

So apply this principle in the code, as the latter will factor changes on the outside, but will not determine the fixed factors of change as the underlying, so late in the expansion and modification of the code efficiency will be more ideal. Meanwhile, each split this code to avoid the retractor in the modification process characteristics affect the whole body, is called encapsulation.

Open for extension, but closed for modification.

Add new features, without changing the original code.

Single Responsibility class (a class definition)

Single Responsibility Principle   

The so-called single finger should be reason for a class can be modified only one , single issue is for the principle of direct coupling of the code, the so-called coupling refers to modifications in the face of the spread of the range, suppose a class there are two or three functions, but each time only because the entire class to modify the same thing happened, other problems will not touch such, the coupling will already dropped to the ideal state, in addition to detailed classification outside this does not affect the work even more difficult late in the code, but also in the time-consuming effort when generating code.

A class has one and only one reason for it to change.

Dependency Inversion (abstract dependent)

Dependency Inversion Principle

Dependence, in the course of object-oriented thinking in the first step is to divide, will need to change the code separated, will not need to change the code to integrate with, so far, we achieved two basic packages, after integration codes often require the transfer of generated code changes, this relationship can be understood as the most direct dependencies.

And when a change in the basis of this relationship will depend on the attendant change, the more change, dependence modify the more.

To avoid late changes lead to increased quantities of the code, the first thing to do is change the code will become a big frame, give them a uniform type, that is unified inheritance, to a parent, the parent class itself is only as a transit point adapter for fixed code region code area and changes, in other words, at this time if you want to call the fixed code area code region changes, we must go through the parent class, by the conventional image conversion codes having dependency relations to depend abstract Code manner, it is called dependency inversion.

The following is an example for demonstration of the code structure, such as "Joe Smith driving a car," this thing, "Joe Smith" and the man "driving" this thing is not going to change in the current framework, the so unified in the package fixed code area, and driving the "car" as the code package may change to change the code region, all subsequent auto reunification inherited by called "carrier" parent class, because there is no particular feature so abstract , and Joe Smith each driving different vehicles they have to point to "vehicle", then the "vehicle" on demand to pick inherited his car each specific subclass, if there is new demand, but also and then continue to expand the subclass.

If you start "Joe Smith" as a person also can replace, or "drive" it also can be replaced, then the same will be "John Doe" package to a change in the region, to inherit called "human" parent; "driving" this thing can inherit similar to "conduct" such an abstract parent class, both to meet the Dependency inversion principle.

Client code ( class calls ) possible dependency ( used ) abstract components.

Abstract is stable. Implementation is changing.

A combination of multiplexing principle (best practices multiplexing)

Composite Reuse Principle

A combination of multiplexing intent refers to the principle of priority when used in combination with a combination of relations and relationships inheritance can meet business requirements . However, according to the whole idea of it, my personal view is that it should be understood as a combination of both multiplexing means generalization, association, dependence (see the relationship between class and class) are case meets the requirements, to make use of which the degree of coupling the lowest relationship . Despite the contrast inherit the coupling relationship is not better than the other two relationships, but does not mean worthless inheritance, in many cases, inherited the practicality is still good.

If only for code reuse preferred composition multiplexing, instead of inheritance to reuse.

Coupling combinations of relatively low inheritance.

Richter replaced (after inheritance rewritten to guide the design of inheritance)

Liskov Substitution Principle

里氏替换针对的依然是继承关系,只要是父类能参与的任何构造,子类完全可以胜任,所以里氏替换的主要思想就是只要父类可以被调用,子类就一定要代替父类被调用。这种情况并不是说父类没有意义,相反的,里氏替换进一步要求父类尽可能不要存在太具体的功能,能抽象就尽量抽象任何的修改都完全依靠子类来补充和修改,从而进一步实现开闭原则(父类对修改关闭,子类对修改开放)。

同时补充一下,因为每一个子类在父类的构造上都可以额外拓展,于是,就算每一个子类内部的方法名字跟父类完全一样,但是因为每个子类都对这同一个方法产生了新的拓展,所以在调用这个方法的时候,方法名始终没有任何改变,但是方法本身却是随着子类的不同而千变万化的。这种现象就称之为多态。所以里氏替换原则也是在为父类的抽象化和子类的多态化进行阐述。

父类出现的地方可以被子类替换,在替换后依然保持原功能。

子类要拥有父类的所有功能。

子类在重写父类方法时,尽量选择扩展重写,防止改变了功能。

迪米特法则(类与类交互的原则)

Law of Demeter

迪米特法则也被戏称为“最少知道法则”,其实说白了就是针对面向对象里的低耦合。它的本意指的是类与类之间尽可能不要有太多的关联,当一个类需要产生变化时,其他的类尽量做到不产生改动。具体的体现其实与上面阐述的单一原则是一致的,既每一个类最好能做到只会被同一件事情影响和改变,其他类尽可能不受其影响。

类与类交互时,在满足功能要求的基础上,传递的数据量越少越好。因为这样可能降低耦合度。

类与类的关系

泛化:子类与父类的关系,概念的复用,耦合度最高;

  B类泛化A类,意味B类是A类的一种;

  做法:B类继承A

关于继承关系,声明一个父类,里面可以内置若干参数,若干方法,而之后声明的子类,只要是继承自这个父类,那么就可以直接获取关于父类的参数和方法,除此之外,子

类还可以拥有自己专属的额外参数和方法,这些新的参数和方法父类是不能享用的。

关联(聚合/组合)部分与整体的关系,功能的复用,变化影响一个类;

   AB关联,意味着BA的一部分;

  做法:在A类中包含B类型成员。

所谓的关联关系,也被称为聚合关系或者组合关系,指的是两个类之间不做直接继承,而是将一个类作为另一个类其中的一个参数进行连接。通过参数连接就避免了继承必须继承所有参数和方法的弊端,在耦合度上相对于继承又下降了许多。

依赖:合作关系,一种相对松散的协作,变化影响一个方法;

   A类依赖B类,意味A类的某些功能靠B类实现;

  做法:B类型作为A类中方法的参数,并不是A的成员。

依赖关系,也被称为合作关系,在关联关系的基础上进一步降低了耦合度,其中一个类的整体将只能作为另一个类的方法中的一个参数来进行调用。

所以对这三种关系进行耦合度排序的话:依赖关系耦合度最低 关联关系耦合度适中 继承关系耦合度相对最高。

Guess you like

Origin www.cnblogs.com/maplethefox/p/10887879.html