Richter's six principles of design patterns Design IOS substitution principle (LSP, Liskov Substitution Principle)

definition

      Substitution principle, there are two definitions of Richter, is said to be proposed by the surname of the women at MIT, so named for its name.

  • Defined 1 : If a type T1 object o1 , both of type T2 object o2 , so to T1 defined program P in o1 all replace o2 , the behavior of the program without any change, so T2 is T1 subclass.
  • Defines 2: All references to place the parent class must be able to transparently use a subclass objects.

Interpretation of the definition

      In fact, the meaning expressed by the two definitions are the same, that is where all of the parent class appears, the subclass can appear, and will replace the parent object is a subclass of the object, the program does not throw any exception or error, so we need to note that, try not to overload or override the parent class method ( excluding abstract method ) , as this may alter the behavior of the original parent.

advantage

  • Code-sharing, reduce the workload of the class is created, each subclass has all the properties and methods of the parent class;
  • Improve code reusability;
  • Improve the code expansion;
  • Improve the openness of the product or project.

Shortcoming

  • Inheritance is invasive, with properties and methods of the parent class;
  • Reducing the flexibility of the code must have the properties and methods of the parent class;
  • Enhanced coupling, the parent class property or method change, need to be considered subclasses.

Questions raised

      A function Pl , by the class A is completed. Now it needs function P1 extend, after the function is expanded to P , wherein P by the original function of P1 and new features P2 composition. Function P by a class A subclass B to complete, then the subclass B in the completion of the new features P2 at the same time, may lead to the original function P1 failure.

solution

      When using inheritance, follow the Richter substitution principle. Class B inherits class A , the method of addition to adding new functions to complete the new P2 outside, so as not to override the parent class A method, try not to overload the parent class A methods.

      Inheritance contain this layer of meaning: the parent class who have achieved good way (relative to the abstract methods), it is in fact a series of set norms and contract, although it is not mandatory for all subclasses must comply with these contract, but if any of these sub-class non-abstract methods modified, it will cause damage to the entire inheritance hierarchy. The Richter substitution principle is an expression of this layer of meaning.

      As for one of the three inherited characteristics of the object, in a huge convenience to programming, but also it brings disadvantages. For example, the use of inheritance will bring invasive procedures, reduced portability procedures, increasing the coupling between objects, if a class is inherited by other classes, then when this class needs to be modified, it must take into account all the sub class, the superclass and modifications, all references are to the functional subclass may malfunction.

Examples

      Or continue our scenario above: Here, we will Employee class as a parent class, there are a method of calculating wages calculateSalary , code as follows:

      .h file:

. 1  @interface the Employee: the NSObject
 2  
. 3  // calculate pay 
. 4 - ( void ) calculateSalary: (NSString * ) name;
 . 5  
. 6  @end

      .m file:

 1 #import "Employee.h"
 2 
 3 @implementation Employee
 4 
 5 - (void)calculateSalary:(NSString *)name
 6 {
 7     NSLog(@"%@的工资是100",name);
 8 }
 9 
10 @end

      调用代码:

1         //调用Employee类的calculateSalary方法
2         Employee *employee = [[Employee alloc] init];
3         [employee calculateSalary:@"张三"];
4         [employee release];

      输出结果如下:

2013-11-26 16:03:37.058 LiskovSubstitutionPrinciple[3305:303] 张三的工资是100

      现在我们为Employee类添加一个子类总监Director类,该类新增了一个职责说明的方法和重写了calculateSalary方法,如下所示:

 1 #import "Director.h"
 2 
 3 @implementation Director
 4 
 5 - (void)calculateSalary:(NSString *)name
 6 {
 7     NSLog(@"总监%@的工资是10000",name);
 8 }
 9 
10 - (void)duty
11 {
12     NSLog(@"总监的职责是管理");
13 }
14 
15 @end

      调用代码:

1         Employee *employee = [[Director alloc] init];  //将所有父类出现的地方都替换成子类
2         [employee calculateSalary:@"张三"];
3         [employee release];

      输出结果如下:

2013-11-26 16:15:19.886 LiskovSubstitutionPrinciple[3429:303] 总监张三的工资是10000

      从上面的结果我们可以看到,由于重写了父类EmployeecalculateSalary方法,造成计算薪资的方法都是调用子类Director重写后的方法。如果应用场景是要求公司的薪资都是统一的,那么调用Director类重写的方法就是不正确的。如果非要重写父类里面的方法,比较通用的做法是:原来的父类和子类都继承一个更通用的基类,原有的继承关系去掉,采用依赖、聚合、组合等关系代替。

      里氏替换原则通俗的来讲就是:子类可以扩展父类的功能,但不能改变父类原有的功能。它包含以下2层含义:

  • 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法;
  • 子类中可以增加自己特有的方法。

      在项目中所有使用子类的地方都可用父类替换,但在调用方法的时候,即呈现面向对象编程的多态性。里氏替换原则,是非常重要的原则,也是相对较难的原则

 

      源码下载   返回目录

转载于:https://www.cnblogs.com/eagle927183/p/3452810.html

Guess you like

Origin blog.csdn.net/weixin_33851604/article/details/93725159