デザインパターンデザインIOS置換原則(LSP、リスコフの置換原則)のリヒターの6つの原則

定義

      置換原理は、リヒターの二つの定義があり、MITでの女性の姓によって提案されたと言わので、その名にちなんで命名されました。

  • 定義1:タイプの場合T1のオブジェクトO1、型の両方のT2のオブジェクトO2にので、T1定義プログラムP中のO1すべて置き換えるO2、そのままプログラムの動作を、ようT2がありますT1のサブクラス。
  • 定義2:親クラスを配置するすべての参照は透過的にサブクラスオブジェクトを使用することができなければなりません。

定義の解釈

      実際には、二つの定義によって表現の意味が同じで、それは、親クラスのすべてが表示される場所、サブクラスが表示されることがあり、親オブジェクトは、オブジェクトのサブクラスで置き換えられますされ、プログラムはそう、任意の例外やエラーをスローしません私たちは、親クラスのメソッドをオーバーロードまたは上書きしないようにしよう、それを注意する必要があります抽象メソッドを除く、これは元の親の振る舞いを変更することができるよう、。

利点

  • コードシェア、クラスの作業負荷を減らすに作成され、各サブクラスは、親クラスのすべてのプロパティとメソッドを持っています。
  • コードの再利用性を向上させます。
  • コード展開を向上させます。
  • 製品やプロジェクトのオープン性を向上させます。

短所

  • 継承は、親クラスのプロパティとメソッドで、侵襲的です。
  • コードの柔軟性を減らすことは、親クラスのプロパティとメソッドを持っている必要があります。
  • 強化されたカップリング、親クラスのプロパティやメソッドの変更は、サブクラス考慮する必要があります。

問題が提起します

      機能P1のクラスによって、Aが完成されます。今では、関数必要P1が機能に拡張された後に、延びP、前記Pの本来の機能によってP1、新しい機能P2の組成物。関数PクラスによってサブクラスBその後完了する、サブクラスB新機能の完了にP2と同時に、元の関数につながる可能性がP1の障害。

ソリューション

      継承を使用する場合は、リヒターの置換原則に従ってください。クラスBは、クラスの継承A、新しい完了するために、新たな機能を追加するだけの方法P2を親クラスに上書きしないように、外部の方法を、親クラスのオーバーロードしないようにしてくださいAの方法を。

      継承は、意味のこの層含まれています(抽象メソッドに対して)良い方法を達成している親クラスをすべてのサブクラスは、これらを遵守しなければならないことは必須ではありませんが、それは、実際には、設定された規範や契約のシリーズですこれらのサブクラスの非抽象メソッドのいずれかが変更された場合、契約は、しかし、それは全体の継承階層への損傷の原因となります。リヒターの置換原則は意味のこの層の表現です。

      3のいずれかのようなプログラミングに大きな利便性で、対象物の特性を継承するだけでなく、それは不利益をもたらします。このクラスを変更する必要がある場合クラスは他のクラスに継承される場合、例えば、継承の使用は、オブジェクト間の結合を増加させる、侵襲的処置、低減移植手順をもたらす、その後、それを考慮にすべてのサブを取る必要がありますクラス、スーパーおよび修正は、すべての参照が誤動作する可能性があり、機能サブクラスにあります。

      以上、私たちのシナリオを続ける:ここでは、私たちがする従業員の親クラスとしてクラス、賃金の計算方法があるcalculateSalary次のように、コードは:

      .Hファイル:

1  @interface 従業:NSObjectの
 2  
。3  //は賃金を計算する
。4 - (ボイド)calculateSalary:(NSStringの* )名;
 5。 
6。 @end

      .Mファイル:

 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

おすすめ

転載: blog.csdn.net/weixin_33851604/article/details/93725159