畅谈JAVA设计模式

    技术2022-05-20  66

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

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

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

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

     

    二:设计模式类型

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

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

         行为模式:命令模式  

    三:模式详细介绍

      单例模式: 

         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

     


    最新回复(0)