畅谈JAVA设计模式

来源:互联网 发布:家庭网络布线图 编辑:程序博客网 时间:2024/04/30 21:16

一:什么时候使用设计模式

 使用设计模式的目的是为了适应未来的变化,变化之所以存在是因为它的不可预知性——如果

可以预知,则不能称其为变化.

  敏捷开发人员不会对一个庞大的设计预先应用那些原则和模式。相反,这些原则和模式被应用在一次次的迭代中,力图使代码以及代码所表达的设计保持干净。

 

二:设计模式类型

     创建模式:单例模式,工厂模式

     结构模式:代理模式,适配器模式

     行为模式:命令模式  

三:模式详细介绍

  单例模式: 

     Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在 .

     在很多操作中,比如建立目数据库连接都需要这样的单线程操作。(也是主要需要的操作) .

    单例的两种实现

代码一:

     public class Singleton {

      private Singleton(){}

      //在自己内部定义自己一个实例,是不是很奇怪?
  //注意这是private 只供内部调用

      private static Singleton instance;

      //这里提供了一个供外部访问本class的静态方法,可以直接访问  
  public static Singleton getInstance() {
    if(instance=null)

                     instance=new instance();

                  return instance;   
   }
}

代码二:

 

     public class Singleton {

       private static Singleton instance = null;

  public static synchronized Singleton getInstance() {
       //
关键字synchronized降低了程序性能,因为同时只能一个用户得到实例
  if (instance==null)
    instancenew Singleton();
  return instance;

           }

     }

 

工厂模式:

 

工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象

     一个专门生产Sample实例的工厂:

 

     public class Factory{

       public static Sample creator (int which){

       //产生Sample 系例类的实例。
  if (which==1)
    return new SampleA();
  else if (which==2)
    return new SampleB();

       }

     }

 

 

  工厂模式是常用的模式。工厂模式的应用情景明确,设计思想简单。用一个静态方法,工厂模式的变化形式有很多。

     将工厂模式稍加变化可以得到建造(Builder)模式。工厂模式的“加工工艺”是隐藏的,而建造模式的“加工工艺”是暴露的。这点不同,使建造模式在更加灵活的同时也有失优雅。 

代理模式:

 

    Proxy是比较有用途的一种模式,而且变种较多,应用场合覆盖从小结构到整个系统的大结构,Proxy是代理的意思,我们也许有代理服务器等概念,代理概念可以解释为:在出发点到目的地之间有一道中间层,意为代理.

    设计模式中定义: 为其他对象提供一种代理以控制对这个对象的访问. 

为何要用代理模式:

 

     某个客户端不能直接操作到某个对象,但又必须和那个对象有所互动.

     举例两个具体情况:

     1.如果那个对象在Internet的某个远端服务器上,直接操作这个对象因为网络速度原因可能比较慢,那我们可以先用Proxy来代替那个对象.

     2.如果你想卖某公司的产品,但又不能直接垄断该企业,那么你可以做这个公司的代理商。

 

     class teacher {

         public void teach()

         {

                System.out.println("教书的方法");

         }

         public void write()

         {

                System.out.println("写的方法");

         }

}

 

      class supply {

        teacher te=new teacher();

        public void teach()

        {

               te.teach();

        }

        public void write()

        {

               te.write();

        }

        public static void main(String []args)

        {

               supply su=new supply();

               su.teach();

        }

      }

关于代理模式的忠告:

 

   如果在一开始就知道某些底层策略一定会被替换掉,那么使用代理来隔离这些策略还是有必

要的。否则,几乎没有使用的必要. 

设计模式之适配器

 

    定义:
将两个不兼容的类纠合在一起使用,属于结构型模式,需要有Adaptee(被适配者)Adaptor(适配器)两个身份.

    为何使用?
我们经常碰到要将两个没有关系的类组合在一起使用,第一解决方案是:修改各自类的接口,但是如果我们没有源代码,或者,我们不愿意为了一个应用而修改各自的接口。怎么办?使用Adapter,在这两种接口之间创建一个混合接口(混血儿).

    如何使用? 

 

      public class SquarePeg{
  public void insert(String str){
System.out.println("SquarePeginsert():"+str);
}

      }

 

      public class RoundPeg{
  public void insertIntohole(String msg){
    System.out.println("RoundPeg insertIntoHole():"+msg);
}
}

 

   现在有一个应用,需要既打方形桩,又打圆形桩.那么我们需要将这两个没有关系的类综合应用.

假设RoundPeg我们没有源代码,或源代码我们不想修改,那么我们使用Adapter来实现这个应用:

 

      public class PegAdapter extends SquarePeg{
private RoundPeg roundPeg;

      public PegAdapter(RoundPeg peg)(this.roundPeg=peg;)

      public void insert(String str){ roundPeg.insertIntoHole(str);}

      }

 

      在上面代码中,RoundPeg属于Adapter,是被适配者.PegAdapterAdapter,Adapter(被适配者RoundPeg)Target(目标SquarePeg)进行适配.

命命令模式:

 

      Command定义
不少Command模式的代码都是针对图形界面的,它实际就是菜单命令,我们在一个下拉菜单选择一个命令时,然后会执行一些动作.

      将这些命令封装成在一个类中,然后用户(调用者)再对这个类进行操作,这就是Command模式

 

    典型的Command模式需要有一个接口.接口中有一个统一的方法,这就是"将命令/请求封装为对象":

 

      public interface Command {

 

 

      public class Engineer implements Command {

  public void execute( ) {
    //do Engineer's command
  }
}

      public class Programmer implements Command {

  public void execute( ) {
    //do programmer's command
  }
}

      public class Politician implements Command {

  public void execute( ) {
    //do Politician's command
  }
}

  public abstract void execute ( );
}

 

     按照通常做法,我们就可以直接调用这三个Command,但是使用Command模式,我们要将他们封装起来,扔到黑盒子List里去:

 

      public class producer{
  public static List produceRequests() {
    List queue = new ArrayList();
    queue.add( new DomesticEngineer() );
    queue.add( new Politician() );
    queue.add( new Programmer() );
    return queue;
  }

      }

这三个命令进入List中后,已经失去了其外表特征,以后再取出,也可能无法分辨出谁是Engineer 谁是Programmer,看下面如何调用

 

    public class TestCommand {
  public static void main(String[] args) {
    
    List queue = Producer.produceRequests();
    for (Iterator it = queue.iterator(); it.hasNext(); )
        //取出List中东东,其他特征都不能确定,只能保证一个特征是100%正确,
        // 他们至少是接口Command"儿子".所以强制转换类型为接口Command

        ((Command)it.next()).execute();  

      }
}

四总结

 

      设计模式的重要性

      设计模式的类型

      常见的几种设计模式:单例,工厂,代理,适配器,COMMAND