1. 程式人生 > >面試三種設計模式

面試三種設計模式

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黏合在一起,使這    兩者可以通訊