面試三種設計模式

1、裝飾模式

    **************************************************************************************************************************

    不改變原內容的情況下,通過創建一個包裝對象即裝飾來包裹真實對象,實現保持對象原有功能並動態擴展。

    **************************************************************************************************************************

    設計原則:多用組合,少用繼承

    利用繼承設計子類的行爲,不僅編譯時靜態決定,而且所有子類都會繼承到相同行爲。利用組合擴展對象,可以         在運行時動態擴展。

         **************************************************************************************************************************

         裝飾模式的特點:

         a、裝飾對象和真實對象有相同接口,這樣客戶端對象就能以和真實對象相同的方式和裝飾對象交互。

         b、裝飾對象包含一個真實對象的引用(reference)

         c、裝飾對象接收所有來自客戶端的請求,並轉發給真實對象

         d、裝飾對象可以在轉發請求之前或之後增加一些附屬功能

         **************************************************************************************************************************

         實用性:(java的io也使用了裝飾者模式)

         a、給類增加一個附屬值

         b、動態增加功能並能動態撤銷功能

         c、小功能的組合排列實現大功能

         d、類定義被隱藏或不能被使用時,或拓展功能需要產生大量子類時可用裝飾模式

         *************************************************************************************************************************

         //定義裝飾者的父類

         public abstract class Decorator implements Drink{

         public Drink drink; //要裝飾的對象

         public Derector(Drink drink){

                this.drink = drink;

         }

         @Override

         public String name() {

                         return drink.name();

         }

         @Override

         public float price() {

                         return drink.price();

         }

         }

         //定義裝飾者類,椰果類

         public class Cocount extends Decorator {

         public Cocount(Drink drink) {

                      super(drink);

          }

          @Override

          public String name () {

                      return "椰果" + super.name();

          }

          @Override

           pulic float price () {

                      return super.price() + 0.8f; //椰果0.8元

          }

          }

          //測試裝飾類

          public class TestDecorator {

          pubic static void main () {

                     Drink drink = new MakeTea();

                     Cocount cocount = new Cocount(drink); //奶茶裏添加椰果

                     System.out.println("第一杯奶茶爲:" + cocount.name() + "價格爲:" + cocount.price());        

          }

          }

2、單例模式

      懶漢式單例、餓漢式單例、登記式單例

      單例模式特點:
      a、只能有一個實例

      b、必須創建自己唯一實例

      c、必須給其他所有對象提供這一實例

      在計算機系統中,線程池、緩存、日誌對象、對話框、打印機、顯卡的驅動程序常被設計成單例。單例模式就是         爲了避免不一致狀態。

      *******************************************************************************************************************************

      a、懶漢式單例:

      第一次調用時,實例化

      public class Singleton {

      private Singleton() {}

      private  static Singleton single = null;

      public static SIngleton getInstance() {  //靜態工廠方法

                 if(single == null) {

                 single = new Singleton();

      }

                 return single;

      }

      } //java反射機制可以實例private的構造方法,這裏不做討論。懶漢式單例模式是線程不安全的。

     /est/測試類

     public class Tmain {

       public static void mian(String[] args)  {

      TestStream ts1 = TestSingleton.getInstance();

      ts1.setName("jason")

      TestStream ts2 = TestSingleton.getInstance();

      ts2.setName("0593");

      

      ts1.printInfo();

      ts2.printInfo();


      if(ts1 == ts2) {

              System.out.println("創建的是同一個實例");

      }else{

              System.out.println("創建的不是同一個實例");

      }

      }

      }

      //結果-創建的是同一個實例,說明單例模式只會創建一個所有線程公用的實例

      b、餓漢式單例模式

      private class Singleton {

      private Singleton () {}

      private static final Singleton single = new Singleton();

      public static Singleton getInstance() {

                return single; 

      }

      }

      c、登記式單例(類似Spring裏面的方法,將類名註冊,下次從裏面直接獲取)

      public class Singleton {

         private static Map<String,Singleton> map = new HashMap<String,Singleton>();

         static{

          Singleton single = new Singleton();

          map.put(single.getClass().getName(),single);

      }

      protected Singleton(){}

      public static Singleton getInstance(String name){

               if(name == null) {

               name = Singeton.class.getName();

               System.out,println("name == null" + "--->name=" + name );

       }

       if(map.get(name) == null) {

                try{

                map.put(name,(Singleton) Class.forName(name).newInstance());

      }catch(InstancetiationException e) {

                e.printStackTrace();

      }catch(IllegalAccessException e) {

                e.printStackTrace();

      }catch(ClassNotFoundException e) {

                e.printStackTrace();

      }

      }

                return map.get(name);

      }  

      //登記式單例實際上維護了一組單例類的實例,將這些實例存放在一個Map(登記簿)中。已登記過的實例,從Map         直接返回;沒有登記過的,登記後返回。

3、適配器模式(包裝模式)

      ocp原則(開閉原則):一個軟件實體應通過擴展增加功能,而不應該通過修改原碼實現變化。

      對象適配器模式和類適配器模式(一般多重繼承)

      *******************************************************************************************************************************

      將一個接口適配成用戶所期待的。適配器允許因爲接口不兼容而不能一起工作的類工作在一起,具體將自己的接         口包裹在一個已存在的類中。

      *******************************************************************************************************************************

      要求接口中規定了所有要實現的方法,但使用時只實現其中的幾個方法。

      *******************************************************************************************************************************

   //標準接口

   interface Target {

             public void request();

   }

   //Adaptor父類,具有所有功能

   class Adaptee {

          public void specificRequest() {

               System.out.println("配給適配器的特殊功能");

   }

   }

   //適配器類

   class Adapter extends Adaptee implements Target {

   public void request () {

             super.specificRequest();

   }

   }

   //測試類

   public class Client {

   public static void main(String[] args) {

         Target concreteTarget = new Target();

         concreteTarget.request();   //普通功能

         Target adapter = new Adapeter();

         adapter.request(); //適配器特殊功能

   }

   } //java不支持多線程,只能採用包裝類實現。其實適配器什麼都沒有做,只是將Adaptee和Target黏合在一起,使這    兩者可以通信

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章