デザインモードの6つの原則-開閉の原則と単一責任の原則の詳細な説明
1.オープンクローズ原則(OCP)
-
概念
開閉の原則の核心は、拡張のために開き、変更のために閉じることです。その目的は、プログラムのスケーラビリティを向上させ、ホットプラグを実現することです。つまり、要件が変更されるたびに、元のコードを変更せずに変更できます。変更。ニーズに合わせて新しい機能を拡張します。
-
シンプルなケース
書店事業:
以下のカテゴリーが利用可能です
1.
Book
このインターフェースには、価格、本のタイトル、著者、基本的なゲッターおよびセッターメソッドなどの属性が含まれていますpublic interface Book { String getName(); int getPrice(); String getAuthor(); }
2.クラスを
NovelBook(小说)
実装しましたBook
public class NovelBook implements IBook{ private String name; //为了防止精度丢失,这里用原有的价格*100的整数来保存 private int price; private String author; public NovelBook(String name, int price, String author) { this.name = name; this.price = price; this.author = author; } @Override public String getName() { return this.name; } @Override public int getPrice() { return this.price; } @Override public String getAuthor() { return this.author; } }
3.
BookStore
書店private static ArrayList<IBook> bookList=new ArrayList<>(); static { bookList.add(new OffNovelBook("红楼梦", 9900, "曹雪芹")); bookList.add(new OffNovelBook("侠客行", 8900, "金庸")); bookList.add(new OffNovelBook("原则", 6900, "瑞达利欧")); bookList.add(new OffNovelBook("海贼王1", 4900, "尾田荣一郎")); } public static void main(String[] args) { System.out.println("卖书的记录如下----------------------"); for (IBook book : bookList) { System.out.println("书籍名称:"+book.getName()+"\t\t作者:"+book.getAuthor()+"\t\t价格:¥"+book.getPrice()/100.0+"元"); } } }
今、そのような新しい需要があります:
ダブルイレブンのおかげで、70元以上の本を20%割引し、70元未満の本を10%割引する必要があります。この需要に今どのように対応する必要がありますか?考えやすくなります。①
NovelBook
このクラスのgetPrice
メソッドを変更する②Book
インターフェイスに新しいメソッドを追加します。上記の2つの方法は多かれ少なかれ不適切です。1つは、getPrice
方法を変更した場合、他の場所で本の通常価格を取得したい場合、それは満たされないため、元の機能が変更されます。2つ目は、新しいためです。メソッドがインターフェイスに追加された場合、このメソッドをすべての実装クラスに追加する必要があります。これにより、変更が必要な場所が増えます。上記で発生した問題については、開閉の原則と組み合わせて、割引を追加できます。割引価格を取得できるようにメソッドOffNovelBook
を継承NovelBook
および書き換える新規カテゴリは、getPrice
このようにして、元のビジネスに影響を与えることなく新しい需要に対応しますコードは次のように表示されます。
public class OffNovelBook extends NovelBook{ public OffNovelBook(String name, int price, String author) { super(name, price, author); } @Override public int getPrice() { int sellPrice=super.getPrice(); int offPrice=0; if(sellPrice>7000){ offPrice=sellPrice*90/100; }else{ offPrice=sellPrice*80/100; } return offPrice; } }
-
総括する:
利点:
1.ソフトウェアテストを容易にします
元のコードは変更されていないため、毎回新しいコードをテストするだけで済みます
2.コードの再利用性を向上させる
粒度が小さいほど、再利用される可能性が高くなります
3.ソフトウェアの保守性を向上させる
開閉の原則に準拠したソフトウェア。毎回新しい機能を拡張するだけで、元の機能にあまり影響を与えないため、安定性が高く、保守が容易です。
2.単一責任原則(単一責任原則、SRP)
-
概念:
名前が示すように、クラスには変更の理由が1つだけ(つまり、他の責任に関連する理由のみ)ある必要があることを意味します。その目的は、複雑さを軽減し、読みやすさと保守性を向上させることです。クラスのすべてが異なる場合を想像してみてください。関係のない方法や属性の種類は間違いなくあなたを魅了します。まるで、一人が複数の役割を持ち、一人がチームであるように。これは単純に見えますが、それは間違いなくその人を非常に疲れさせます。それに関連するすべてが関連している限り彼に。特別な説明が必要なのは、責任分担に独自の解決策がないため、状況に応じて誰もがどのように分担するかを決めることができるということです。
-
単純なケース:
呼び出し関数を実装します。
Phone
ダイヤル、通話、電話を切るいくつかの方法を定義するインターフェイスpublic interface Phone { //拨号 void dial(String phoneNumber); //通话 void chat(Object obj); //挂断 void hangup(); }
単純に分析します。
上記のデメリット:
1.クライアントが1つの責任のみを必要とする場合、他の不要な責任を含める必要があり、コードの冗長性が発生します
2.特定の責任の変更により、このクラスが他の責任を実行できるようになる可能性があります。素人の言葉で言えば、短時間は忙しすぎる可能性があります。
注意深く分析した後、ダイヤルと電話を切る2つの方法がプロトコルに関連しており、通話がデータ送信に関連していることを見つけるのは難しくありません。したがって、分析に従って責任を分割できます。
public interface DataTransfer { void chat(Object obj); }
public interface ConnectionManger { void dial(String phoneNumber); void hangup(); }
-
総括する
利点:
1.複雑さを軽減する
クラスは1つの責任のみを担当し、ロジックは比較的単純です
2.読みやすさを向上させる
複雑さが軽減されるため、読みやすさが向上します
3.保守性を向上させる
読みやすさが向上すると、保守性も向上します
4.変更によるリスクの軽減
単一責任の原則によれば、機能が変更されると、他の機能への影響が大幅に減少します