【JAVA】設計モード

9908 ワード

https://blog.csdn.net/jack__chiang/article/details/70208886
1.設計パターンの分類
作成型モードは、工場メソッドモード、抽象工場モード、単例モード、構築者モード、プロトタイプモードの5種類です.
構造型モードは、アダプタモード、アクセサリーモード、エージェントモード、外観モード、ブリッジモード、コンビネーションモード、メタモードの7種類があります.
行動型モードは、計11種類:ポリシーモード、テンプレートメソッドモード、オブザーバモード、反復器モード、責任チェーンモード、コマンドモード、メモモード、状態モード、訪問者モード、仲介者モード、解釈器モード. 
1.ファクトリモード(Factory Method):
  •     一般工場モード
  •     複数のファクトリメソッドパターン
  •      スタティックファクトリメソッドモード
  •  1.1一般工場モデル:
       複数のクラスが同じインタフェースを実装している場合、これらのクラスのインスタンス化は、「ファクトリクラス」で統一されます.
      
        // 1.           
        public interface Sender {  
            public void Send();  
        } 
    
        //2.1 .         
        public class MailSender implements Sender {  
            public void Send() {  
                System.out.println("    !");  
            }  
        }  
    
        //2.2 .         
        public class SmsSender implements Sender {  
            public void Send() {  
                System.out.println("    !");  
            }  
        }
    
        // 3        
        public class SendFactory {  
            //    
            public Sender produce(String type) {  
                if ("mail".equals(type)) {  
                    return new MailSender();  
                } else if ("sms".equals(type)) {  
                    return new SmsSender();  
                } else {  
                    System.out.println("        !");  
                    return null;  
                }  
            }  
        } 
    
    
    
    
        //   
        public class FactoryTest {  
    
            public static void main(String[] args) {  
                SendFactory factory = new SendFactory();  
                Sender sender = factory.produce("sms");
                sender.Send();  
            }  
        } 
    

                
    1.2複数の工場モデル
    通常のメソッド・モードに基づいて、下文字をフィルタすることなく、ファクトリ・クラスにクラス・インスタンスを作成する方法を直接提供します.
    //          ,   SendFactory   
        //                    
        public class SendFactory {  
    
            public Sender produceMail(){  
                return new MailSender();  
            }  
    
            public Sender produceSms(){  
                return new SmsSender();  
            }  
        }
    
        //   
        public class FactoryTest {  
    
            public static void main(String[] args) {  
                SendFactory factory = new SendFactory();  
                Sender sender = factory.produceMail();  
                sender.Send();  
            }  
        }  
    

    1.3静的工場方法モード
    上記の複数のファクトリメソッドモードのメソッドを静的に設定し、インスタンスを作成する必要がなく、直接呼び出します.
    public class SendFactory {  
    
            public static Sender produceMail(){  
                return new MailSender();  
            }  
    
            public static Sender produceSms(){  
                return new SmsSender();  
            }  
        }  
    
        //   
        public class FactoryTest {  
    
            public static void main(String[] args) {      
                Sender sender = SendFactory.produceMail();  
                sender.Send();  
            }  
        }  
    

    まとめ:1つのインタフェースの複数のクラスのインスタンス化を実現する際に、「ファクトリクラス」を作成し、これらのクラスのインスタンス化プロセスを統一的に管理する.
     2.抽象工場モデル:
    「工場クラス」を抽象化:
          :
        //          
        public interface Sender {  
            public void Send();  
        } 
    
        //        
        public class MailSender implements Sender {  
            public void Send() {  
                System.out.println("    !");  
            }  
        }  
        //        
        public class SmsSender implements Sender {  
            public void Send() {  
                System.out.println("    !");  
            }  
        }  
    
        //        
        public interface Provider {  
            public Sender produce();  
        }  
        //        
        public class SendMailFactory implements Provider {  
            public Sender produce(){  
                return new MailSender();  
            }  
        }  
        public class SendSmsFactory implements Provider{  
            public Sender produce() {  
                return new SmsSender();  
            }  
        }  
    
        //   
        public class Test {  
    
            public static void main(String[] args) {  
                //        
                Provider provider = new SendMailFactory(); 
                //                
                Sender sender = provider.produce();  
                sender.Send();  
            }  
        } 
    

    まとめ:以前は1つの工場クラスが複数の最終クラスをインスタンス化することができ、現在は複数の工場クラスであり、各工場クラスは1つの最終クラスをインスタンス化するだけで、最終クラスの多様性を工場クラスの多様性に移す.
               簡単に言えば、マルチステート性を利用するのと同様に、B extends A、Bで書き換えられたAのメソッドが、Aの作成時にA a=new B()を呼び出す場合、後続のaのメソッドの呼び出しは実際にBの呼び出しを呼び出す.
                  Provider provider = new SendMailFactory();  Providerは抽象クラスで、providerは抽象クラスのインスタンス化オブジェクトで、providerを修正した後の操作に向かって、newの後ろの方法を修正して、開拓性を増やすことができます!!!
    実はクラスを書いて、SendMailFactoryを継承することもできますか?
    3.単例モード(Singleton)
      Javaアプリケーションでは、単一のオブジェクトが1つのJVMに存在することを保証します.このようなモードにはいくつかのメリットがあります.
      1.同じクラスを繰り返し作成するシステムの圧力を減らす.
      2.newを省き、GCを軽減する.
    //TODO
    4.ビルダーモード(Builder)
    Googleソースコードでよく見られるモードで、クラスはメンバー変数をさらに「記入」する方法を作成しています.
    class A {
       int a;
       long b;
       string c;
    
       void set_a(int new_a){ ... }
       void set_b(long new_b){ ... }
       ...
       ...
       int get_a();
       long get_b();
       ...
    }

    5.プロトタイプモード(Prototype)
    1つのオブジェクトをプロトタイプとして複製、クローン化し、元のオブジェクトと類似した新しいオブジェクトを生成します.Javaでは、clone()によって複製オブジェクトが実現されます.
        public class Prototype implements Cloneable {  
    
            public Object clone() throws CloneNotSupportedException {  
                Prototype proto = (Prototype) super.clone();  
                return proto;  
            }  
        } 
    

    プロトタイプクラスは、Cloneableインタフェースを実装するだけで、cloneメソッドを上書きします.ここでcloneメソッドは任意の名前に変更できます.Cloneableインタフェースは空のインタフェースなので、cloneAやcloneBのような実装クラスのメソッド名を任意に定義できます.ここではsuper.clone()という言葉に重点を置いているため、super.clone()はObjectのclone()を呼び出します.メソッド、Objectクラスではclone()はnativeであり、java言語//ODOを使用して実装されていないことを示しています.  FURTHER DISCUSSING
    Structureモード
    6.アダプタモード(Adapter)
    6.0クラスのアダプタモード
        A extends B implement C

    このようにAのインスタンスオブジェクトでは、Bで実装された方法を呼び出すことも、Cの方法を呼び出すこともできる.BとCが通信を必要とする場合、直接Aでパラメータ処理を行うことができる.
    6.1オブジェクトアダプタモード
    に似ている
    class A implement C {
    
       public A( B b){
           this.b = b;
       }
    }

     BはAの構造パラメータで、Aのインスタンスオブジェクトの中で直接Bの情報を呼び出すことができて、同時にAはCの実現クラスで、Aの中でCのパラメータを呼び出すことができて、最終的にB/C通信;
    6.2インタフェースアダプタモード
    Aはインタフェースクラス、Bは抽象クラスであり、同時にA,C extends Bを実現し、書き換え方法
    public interface A {
        public void method_A();
    }
    
    public abstract B implement A {
        public void method_A(){
            ....
        };
    }
    
    class C extends B {
        //   
        public void method_A(){
            ....
        };
        public void method_C(){
          ... ...
        }
    }

    3つのアダプタモードのまとめ:
  • クラスのアダプタモード:あるクラスを別の新しいインタフェースを満たすクラスに変換したい場合、クラスのアダプタモードを使用できます.
  • オブジェクトのアダプタモード:あるオブジェクトを別の新しいインタフェースを満たすオブジェクトに変換する場合、元のクラスのインスタンスを保持し、新しいクラスでインスタンスを呼び出す方法で新しいクラスを作成できます.
  • インタフェースのアダプタモード:1つのインタフェースのすべてのメソッドを実装したくない場合は、抽象クラスを作成し、インタフェースのすべてのメソッドを実装することができ、他のクラスを書くときは、抽象クラスを継承します.
  • 7.デコレーションモード(Decorator):既知のクラスで定義されたメソッドの動的拡張を実現
    インタフェースAは、実装クラスCの構成パラメータとすることができるので、インタフェースAの他の実装クラスBは、C(およびサブクラス)の構成パラメータとしてもよく、最終的にインタフェースAを定義する方法func_A()を実現する  のダイナミックな新機能;
    注意:クラスBとクラスCは、最後にfunc_A()が呼び出されたときに、実行されたコードと同時にBとCのfunc_Aの書き換えを含むために、同じインタフェースAを実装する必要があります.
    public interface A {
        public void func_A();
    }
    
    
    public class B implements A {
    
        public void func_A() {
            ... ...
        }
    }
    
    
    public abstract class C implements A {
    
        private A a;
        public C(A a) {
           this.a = a;
        }
        
        public void func_A() {
            this.a.func_A();
        }
    }
    
    
    public class D1 extends C {
        public D1(A a){
            super(a);
        }
    
        public void func_A (){
            func_D1();
            super.func_A ();
        }
    
        public void func_D1() {
          ... ...
        }
    }
    
    
    
    public class D2 extends C {
        public D2(A a){
            super(a);
        }
    
        public void func_A (){
            super.func_A ();
            func_D2();
        }
    
        public void func_D2() {
          ... ...
        }
    }
    
    
      testing code   ///
    
    
    
    public class test {
    
    
       A test_a = new D2(new D1(new B()));
    
       test_a.func_A();
    
    }

      A a = new D2(new D1(new B()));
     D 1とD 2はいずれもextends Cであり、Cのコンストラクション関数では、C独自の変数としてAのインスタンスを保存することができるので、B(実装C)とD 1/D 2はいずれもD 1/D 2のパラメータとして使用することができる
    だからtest_a.func_A();最後の実行は   
    D2::func_A()
    ---> 1 .  D1::func_A() --->1.1 D1::func_D1()
                                       ---->1.2 B::func_A()
          2 .   D2::func_D2()
    最後の実行結果は次のとおりです. func_D1() +B::func_A() ,+func_D2()  最終的にfunc_A()を拡張する目的を達成した.
    8.エージェントモード(Proxy)
      BクラスとCクラスは同時にインタフェースAを実現し、Bクラスはcクラスの実例であり、Cクラスでfunc_Aを書き換え、最後にA a=new C()を書き換える.Cクラスで書き換えたfunc_A対Bに達する クラスのfunc_Aを拡張
        public interface A {  
            public void func_A();  
        }    
    
        public class B implements A{  
    
            public void func_A() {  
                ... ...  
            }  
        }
    
        public class C implements A {  
    
            private A a;  
            public C (A a){  
                this.a = a;  
            }  
            public void func_A() {  
                before();  
                a.func_A();  
                atfer();  
            }  
            private void func_C1() {  
                System.out.println("after proxy!");  
            }  
            private void func_C2() {  
                System.out.println("before proxy!");  
            }  
        } 
    
    
    /testing code///
    
        public class test{  
            public static void main(String[] args) {  
                B b = new B();
                C c = new c(b);  
                c.func_A();  
            }  
        } 
    

     1.被エージェントのオブジェクトはproxyクラスの実参として、proxyクラスに被エージェントクラスのインスタンスがあることを保証し、さらに被エージェントクラスのfuncを拡張する.
     2.被エージェントクラスとエージェントクラスは同じインタフェースの実装であるため、多態に基づいてクラス間の「変換」を実現する.
    1.静的エージェントクラス
    プログラマが作成したり、特定のツールでソースコードを自動的に生成したりしてコンパイルします.プログラムが実行される前に、エージェントクラスの.classファイルはすでに存在します.
    2.動的エージェントクラス:プログラム実行時に、反射機構を用いて動的に作成する
    動的エージェントクラスのバイトコードは、プログラマが手動でソースコードを記述することなくjava反射ブレーキによって動的に生成されます.
    スタティツクエージェント