プログラム設計の七つの原則
まず、開閉の原則
我々は、機能モジュールは、拡張のために開くために設計されたが、変更のために閉じ:インタフェース(アブストラクト)プログラミング(マルチステート特性)の使用を、同時に機能拡張ニーズを実現するために、元のコードを変更することはできません。オブジェクトの再利用性、保守性、柔軟性を向上させます。
要約は、我々は拡張エンティティオブジェクトの実装に固有の実装の詳細を抽象的思考で作成した固形物を、構築したい、と言います。
具体的には、機能的なビジネス要件は、拡張に行くことができますが、達成されている機能は、変更に行くべきではありません。
要件:シンプルなファクトリパターンと理解するためのファクトリメソッドパターン開閉原理を。
分析:
工場出荷時のパターンは、我々は結果だけを気に、オブジェクトがどのように生成されるかを気にしないオブジェクトモデルビルダーのインスタンスを取得することです。
シンプルなファクトリパターンは、オブジェクトのインスタンスを取得するための、比較的単純なビジネスシナリオに直面しています。私たちは、事業を関連パラメータを渡す必要があるので、適切な判断を行うための単純なファクトリオブジェクト、およびそのインスタンスオブジェクトを対応する米国に戻りました。たくさんのことを行うためのファクトリオブジェクトは、彼が違反単一責任の原則を私たちは工場出荷時のオブジェクトを変更することでなければならないときには、事業の拡大経営判断を追加する必要がある場合、オブジェクトの対応する新しいインスタンスを返します。これは、開閉の原則に反します。
public class FruitsFactory { /** * @description: * @param fruitsName * @return com.lmc.gp13280.pattern.factory.fruits.IFruits * @date 2019/5/23 15:44 * @author lmc */ public IFruits product(String fruitsName){ if(null != fruitsName && fruitsName != ""){ System.out.println("客户需求的水果是"+fruitsName); if("苹果".equals(fruitsName)){ System.out.println("水果工厂生产了苹果"); return new Apple(); } if("橙子".equals(fruitsName)){ System.out.println("水果工厂生产了橙子"); return new Orange(); } if("香蕉".equals(fruitsName)){ System.out.println("水果工厂生产了香蕉"); return new Banana(); } return null; }else{ return null; } } }
上記は、私はイチゴにしたい場合は、必要である、果物の工場でコードを変更するイチゴの生産を達成するために。
Abstract Factoryパターンの方法は、サブクラスファクトリオブジェクトが実装するファクトリインタフェースの特定のインスタンスを可能にファクトリインタフェースです。私たちは、それだけに対応するサブクラスファクトリ実装クラスを見つけるために、オブジェクトの特定のインスタンスをしたい、必要の事業拡大ならば、我々は、ライン上の新しいサブクラスの工場を追加するには、元の工場出荷時のサブクラスのみ必要性を変更する必要はありません。これは、事業の拡大を可能にしますが、元のプログラムロジックを変更しません。フォローオン・オフ原則と単一責任の原則を。
public interface IFruitsFactory { /** * 工厂的生产方法 * @return IFruits */ IFruits product(); }
public class AppleFactory implements IFruitsFactory { @Override public IFruits product() { System.out.println("苹果工厂只生产苹果"); return new Apple(); } }
public class BananaFactory implements IFruitsFactory { @Override public IFruits product() { System.out.println("香蕉工厂只生产香蕉"); return new Banana(); } }
public class OrangeFactory implements IFruitsFactory { @Override public IFruits product() { System.out.println("橙子工厂只生产橙子"); return new Orange(); } }
私たちは、彼らのビジネスを拡大するために、特定の果実植物を追加したい、上記のサンプルコードは、行のインターフェイス植物の果実植物を実装するために対応するサブクラスを追加する必要があります。
事業拡大を実現し、元のプログラムは、開閉の原則に従うことで変更されません。
第二に、依存関係逆転の原則
誰もが、実際には、依存関係逆転の原則プログラムオブジェクトが他のオブジェクトに依存している、それは彼らの抽象に依存している必要があり、馴染みのある実装に依存しないことを春の依存性注入、オブジェクトの基礎となる具体的に依存しない、トップレベルのオブジェクトに依存している必要があります。プログラムの具体的な実現は、実装クラスを達成することであるが、私たちは、依存関係逆転で逆さまに、あるトップレベルのインタフェースオブジェクトの実装クラスに依存するつもりですので。
依存関係反転原理は、マルチ状態動作の中核である、コンパイル時ではなく、オブジェクトのインスタンス化のサブクラスへのプログラムは、仮想マシンは、プログラムの実行時に特定のサブクラスオブジェクトの例を選択するようになります。
プログラミングでは、一般的なインタフェース定義まあ、それは簡単に変更されません。、成熟したシステムでは、インターフェイスを変更するので、デザインが復興の打倒に相当し、そしてあなたは、このようなAのことを行うことを喜んでいますか?しかし、実装クラス、代わる新しい実装クラスを追加し、少し変更し、または変更を言うことができます。あなたはその実装クラス限り、実装クラスの変化に依存している場合は、プログラマの災害が入って来ていませんか?あなたは私たちの残りの部分へのトップレベルインターフェースに依存している場合、このインターフェイスのコードに依存しているすべての変更を行う必要はありません、インタフェースがああ変更されていないので、実装インタフェースという、唯一のビジネスロジックの特定のニーズや新たなビジネスサブクラスに変更します。これは、初期の作品オフはできません。
反転を頼ることにより、クラスとクラスの間の結合を低減し、システムの安定性を向上させる、コード向上させることができる
可読性と保守性を、プログラムを変更することによって引き起こされるリスクを低減することができます。
/**
* 水果店
* @author: maocheng.liao
* @create: 2020-02-23 15:20
*/
public class FruitShop {
private IFruitsFactory fruitsFactory;
public IFruitsFactory getFruitsFactory() {
return fruitsFactory;
}
public void setFruitsFactory(IFruitsFactory fruitsFactory) {
this.fruitsFactory = fruitsFactory;
}
/**
* @description:
* @param :从水果生产基地去进货水果
* @return com.lmc.gp13280.pattern.factory.fruits.IFruits
* @date 2020/2/23 15:34
* @author maocheng.liao
*/
public IFruits getFruits(){
IFruits fruits = fruitsFactory.product();
return fruits;
}
}
/**
* 水果店依赖倒置测试
*
* @author: maocheng.liao
* @create: 2020-02-23 15:25
*/
public class FruitShopTest {
public static void main(String[] args) {
IFruitsFactory fruitsFactory= new AppleFactory();
FruitShop fruitShop=new FruitShop();
fruitShop.setFruitsFactory(fruitsFactory);
IFruits apple = fruitShop.getFruits();
apple.getName();
fruitsFactory = new BananaFactory();
fruitShop.setFruitsFactory(fruitsFactory);
IFruits banana = fruitShop.getFruits();
banana.getName();
fruitsFactory = new OrangeFactory();
fruitShop.setFruitsFactory(fruitsFactory);
IFruits orange = fruitShop.getFruits();
orange.getName();
}
}
上記のコードは、最も単純な実装に依存反転され、我々は果物や果物店の生産にどのような果物の生産基地に依存し、どのような購入の果物にするように、果物やフルーツファクトリインタフェースインターフェイスで購入果物の果物の生産基地で果物屋を頼っ私は何の果物に行きたいです。むしろ、特定の工場実装クラスの果物やフルーツ、具体的な実装クラスに頼るより。
- 注:いくつかの簡単なコードは、ブログのアドレスを参照して、詳細なコードが表示されませんでしたします。https://www.cnblogs.com/programmerkaixin/p/10918844.html
第三に、単一責任の原則
私は、単一の責任があると思いデメテルの反射。
シングル責任原則:おせっかいやって手に特化した、イタリアを知っている名前を参照してください、ありません。クラス、インタフェース、メソッド、その職務を担当するだけのために。後にプログラム変更のための責任は、そのプログラムの責任には影響しません。高凝集、低カップリング手順は、単一の責任、労働者の明確な部門、可読性、保守性に従わなければなりません。
最も単純な例:私たちは人間の手の目を置き換えることはできませんが、目は手と足を交換することはできません。
肥大化した言葉がよく、単一責任の原則、それを反映していないのですか?コードがそのように肥大化し書かれている、それは良いプレーすることはできません。
第四に、インタフェースの分離の原則
私が思うに、インタフェース分離の原則がある単一責任の原則反射するだけでなく、デメテルの反射。
オブジェクト指向プログラミング、すべてのものがオブジェクトです。
界面偏析原理:単一の肥大化インタフェースを定義するのではなく、より洗練され専門インターフェースの明確な区分を定義します。肥大化したインターフェースのために、私たちではない具体的な実装では、これは確かだろう単一責任の原則に反します。
最も単純な例:オブジェクトのためのファミリーカー、大型に、それは車のクラスに属し、彼は車のカテゴリーに属し、彼は車のクラスに属すると述べました。それは家族の車のカテゴリ、専用車クラスに属していることを小さなします。
V.デメテル
デメテルも知られている以上の原則として知られているだけでなく、単一責任の原則の味とインターフェース分離。
デメテル:低究極のDOを達成するためにどのようにカップリング、およびオブジェクトのみの自分の本当の関係に依存しています。私の任務外のオブジェクトはすべて背けました。
私は、これは、単一の責任、デメテルはうまくそれを達成するように、何も言うことはありませんだと思います。
第六に、リヒターの置換原則
公式の定義:任意の基底クラス(親クラス)が発生する可能性があり、特定のサブクラスが発生する可能性があります。代替原則リヒターは礎石が派生クラスは、基本クラスを置き換えることができた場合にのみ、機能のソフトウェアユニットが影響されない、基底クラスが本当に派生クラスでも上のベースクラスに基づいて増加することができ、再利用できる多重継承しました新しい動作。サブクラスのインスタンスはスーパークラスのすべてのインスタンスを置き換えることができるはずと、それはそれらの間の関係を有する-Aです。
私は理解して:リヒターの置換原則をオブジェクト指向プログラミングでは、相続の広がりを、制約するためには、使用の継承にある-Aとの関係を持っている必要がありますが、継承の使用を容易にするために、特定のビジネスニーズを達成するために行くことができませんそして、継承。
前提条件:各メソッド呼び出しの前に、メソッドが引数の正しさを確認する必要がありますが、この方法を実行するための唯一の権利を通過した、または契約の発信者に違反することを、実行されません。これは、前提条件として知られています(Pre-condition
)。
事後条件:前提条件の検証プロセスを実行しなければならない、と実行結果を事後条件と呼ばれる契約、に沿って保証されなければならないと(Post-condition
)。これは、戻り値に沿ったものです。
またリヒター原則制約:継承がある場合には、前提条件のサブクラスのメソッドは、同じ前提スーパークラスメソッドカバーや緩いでなければならず、かつ事後条件サブクラスのメソッド必見同じスーパークラスのメソッドは事後条件またはより厳格をカバー。
継承と承継が、実際に継承を継承する時間がありません。
七、合成多重化原理
ここでは、原則として、より良い効果を多重依存関係逆転の原則の合成を組み込みました。
組み合わせ(HAS-A):アナログアセンブリコンピュータ、メモリ、ハードドライブ、cpu
組成物は、それらの間にコンピュータグラフィックス??????、それらの間には関係がありません。これは、関係の組み合わせ、同じライフサイクルです。
重合contanis-a
():アナログ従業員は部門に集約しました。従業員や部門は、1つまたは2人の従業員の離職率が部門オブジェクトには影響しませんが、互いに独立しています。部門の溶解は、従業員のオブジェクトには影響を与えません。
関係の組み合わせ、重合の間の関係を利用するプログラムを多重化:原則を多重化の合成。ビジネスニーズを達成するために、継承の使用を最小限に抑えます。
相続のすべては、すべてのサブクラスにさらされることになります。クラスの親クラスを変更し、カプセル化を解除し、それは、サブクラスに影響を与えます。高い結合。
組み合わせ、重合はよく依存関係逆転の原則、開閉の原則に従うことができます。新しいオブジェクトのオブジェクト部材(重合物の組合せ)の実装の詳細は隠されています。
依存性逆転の原則の原則に多重の合成は、良いの原則は、開閉に従ってください。リーチプログラムの可用性、非常に次元の、高読めます。
なぜ春牛そう?なぜ春の依存性注入?なぜ春は軽量で?