面试三种设计模式

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黏合在一起,使这    两者可以通信

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