[C ++]「クラスManがクラスFireplaceのサブタイプになれない理由」の例に関する契約およびLSP原則による設計

Lisk Substitution Principle(LSP)およびContract Design(DbC)は、この英語版PDFで詳しく説明されています

私は2つの言葉でそれが何であるかを説明します:
DbC :関数には前提条件と事後条件が提供されます。 関数は、前提条件が満たされた場合にのみ実行を開始します。 完了後、関数は事後条件とクラス不変条件が満たされていること、一貫性があることを保証します。

LSPは、あるクラスが別のクラスのサブタイプになり得るかどうかを判断する1つの方法です。 IS-A関係に基づいています。 クラスの外部の類似性だけでなく、派生クラスのオブジェクトの基本クラスへの参照を使用する場合の動作の互換性の観点からも。

コード例を使用して、FireplaceクラスからHumanクラスを継承できない理由を示します。

#include <iostream>
#include <cassert>

class Fireplace {
public :
// (.. ) 18
Fireplace() : temperature(18) { }

// -
int getTemperature() const {
return temperature;
}
// -
void setTemperature( int N) {
temperature = N;
}

// N
virtual void heat( int N) {
// preconditions
int old_temperature = getTemperature();
// 800
assert(getTemperature() + N < 800);

std::cout << " " ;
setTemperature(getTemperature() + N);

// postconditions
// + N
assert(getTemperature() == old_temperature + N);
}
private :
int temperature;
};

class Human : public Fireplace {
public :
Human() { setTemperature(36); }

virtual void heat( int N) {
// preconditions
int old_temperature = getTemperature();

assert(getTemperature() + N < 800); // assert , ..
// 800 -

// 45
// assert:
// assert(getTemperature() + N < 45);
//
// !

// DbC:
// 1) ,
// 2) ,

// - Human Fireplace
// .. LSP,
// /
//


std::cout << " " ;
setTemperature(getTemperature() + N);

// postconditions . .
// + N
assert(getTemperature() == old_temperature + N);
}
};

int main()
{
Fireplace *f = new Human;
f->heat(600);

return 0;
}


* This source code was highlighted with Source Code Highlighter .


ところで、暖炉が最大45度しか加熱できない場合、LSPの観点からは、暖炉のサブタイプになります:)
この記事が誰かを助けてくれて、これらの原則を少し明確にしてくれたら嬉しいです。

Source: https://habr.com/ru/post/J72907/


All Articles