常见的设计模式

设计模式常常分为如下三类:

    创建型:创建对象时,不在直接实例化对象;而是根据特定场景,由应用程序来确定创建对象的方式,从而保证更高的性能,更好的架构优势。创建型模式主要有简单工厂模式、工厂方法、抽象工厂模式、单列模式、生成器和原型模式。

    结构型:用于帮助多个对象组织成更大的结构。结构型模式主要有适配器模式、桥接模式、组合器模式、装饰器模式、门面模式、享元模式和代理模式。

    行为型:用于帮助系统间各对象的通信,以及如何控制复杂系统中的流程。行为型模式主要有命令模式、解释器模式、迭代模式、中介者模式、备忘录模式、状态模式、策略模式、模板模式、访问这模式。

1、单列模式

      有些时候,运行自由创建某个类实例没有意义,还有可能造成系统性能下降(因为创建对象所带来的系统开销问题)。

     主要点:

           1)将构造器用private修饰

           2)提供一个public  static方法,供获取该类对象

           3)该类需缓存一个已经创建的对象,否则该类无法知道是否已经创建对象。

        示例如下:

           class Singleton{

                 private static Singleton instance;

                 private Singleton(){

                   }

                  public static Singleton getInstance(){

                       if(instance == null){

                             instance = new Singleton();

                          }

                         return   instance;

                   }

                }

2、简单工厂模式

      将多个对象交给工厂来生成的设计方式被称为简单工厂模式。

      例如A类依赖于B类。对于A类而言,它并不关心B对象的实现、创建过程。考虑B类实现一个IB接口,而A类只需要与IB接口耦合——A类并不直接使用new关键字来创建B实例,而是重定义一个工厂类:IBFactory,由该工厂来负责创建IB实现,而A类通过调用IBFactory工厂的方法来得到IB的实例。

      下面一个简单的实例来说明简单工厂模式:假设有个Computer对象需要依赖一个输出设备(Printer对象)。让Computer类依赖output属性,将computer类与printer类实现分离,Computer对象只需面向output接口编程即可。computer对象具体依赖哪个实现类完全透明。

      public class Computer{

            private Output out;

            public Computer (Output out){

                this.out = out;

             }

          public void keyIn(String msg){

                 out.getData(msg);

           }

           public void print(){

               out.out();

            }

         public static void main(String[] args){

            outputFactory of =new outputFactory ();

            Computer c = new Computer(of.getOutput());

            c.keyIn("轻量级java“);

            c.print();

         }

     }

以上代码可以看出computer类与printer类已经分离了,只是与该接口耦合。而且Computer不再负责创建output对象,系统将提供一个Output工厂类负责生成output对象,outputFactory工厂类如下:

          public class OutputFactory{

                   public Output getOutput(){

                       return new Printer();

                  }

             }

     以上类提供一个getOutput()方法,该方法返回一个output实例,该方法负责创建output实例,具体创建哪一个实现类的对象,则由该方法决定。

        程序清单:   Printer.java代码如下:

             public class Printer{

                     private String[] printData = new String[MAX_CACHE_LINE);

                       //用以记录当前需打印的页数

                     private int dataNum=0;

                     public void out(){

                            //z只要有作业,继续打印

                            System.out.println("打印机打印:” + printData[0];

                             //把作业队列整体前移一位,并将剩下的作业数减一

                            System.arraycopy(printData,1,printData,0,--dataNum);

                      }

                }

               public void getData(String msg){

                          if(dataNum >= MAX_CACHE_LINE){

                                 System.out.println("输出队列已满,添加失败“);

                            }else{

                                 printData[dataNum++] = msg;

                            }

                 }

           }

     上面的printer类模拟了一个简单的打印机,如果系统需要重构,需要使用BetterPrinter来代替Printer类,则需要让BetterPrinter师兄Output接口,并改下OutputFactory类的getOutput()方法。

      将OutputFactory类的getOutput()方法改成如下:

            return new BetterPrinter();

   通过这种方式,可以把所有生成Output对象的逻辑集中在OutputFactory工厂类中管理,所有需要Output对象的类需要与Output接口耦合,而不是与具体的实现类耦合,即使系统中有很多类依赖Printer对象,只需要修改OutputFactory类的getOutput()方法,返回BetterPrinter对象即可。

        使用简单工厂模式的优势:让对象的调用者和对象的创建过程分离,当对象调用者需要对象时,直接向工厂请求即可,从而避免对象的调用和对象的实现类以硬编码方式耦合。以提供系统的维护性、扩展性。但工厂模式有个小缺陷:当产品修改时,对应的工厂类也需要修改。

3、抽象工厂

    在简单工厂模式里,系统使用工厂类生产所有产品实例,且改工厂类决定生产哪个类的实例,即该工厂类负责所有的逻辑判断、实例创建工作。

    如果不想在工厂类中进行逻辑判断,程序为不同的产品类提供不同的工厂,不同的工厂类生产不同的产品。例如为上面的Printer、BetterPrinter提供PrinterFactory和BetterFactory工厂类。

    本示例将2中的outputFactory该为一个接口,并为该接口提供两个实现类:PrinterFactory和BetterPrinterFactory 

     OutputFactory接口代码如:

      public  interface OutputFactory{

          Output getOutput();

       }

       PrinterFactory实现类如下:

         public class PrinterFactory implements  OutputFactory{

              public Output getOutput(){

                 return new Printer();

             }

           }

       BetterPrinterFactory 实现类如下:

            public class BetterPrinterFactory implements  OutputFactory{

              public Output getOutput(){

                 return new BetterPrint();

             }

           }

    修改2中的Couputer类如下:

               public class Computer{

            private Output out;

            public Computer (Output out){

                this.out = out;

             }

          public void keyIn(String msg){

                 out.getData(msg);

           }

           public void print(){

               out.out();

            }

         public static void main(String[] args){

            outputFactory of =new PrinterFactory ();

            Computer c = new Computer(of.getOutput());

            c.keyIn("轻量级java“);

            c.print();

         }

     }

    当程序需要调用Output对象的方法时,需要显示的创建不同的工厂实例。程序中创建的是PrinterFactory 实例。这种方式虽然不会修改工厂类的方法,但会带来另一种耦合,客户端代码和工厂类的耦合。

    在这种模式下新增一个OutputFactoryFactory工厂类,改工厂类提供了一个getOutputFactory(String type)方法,改方法用于返回一个OutputFactory工厂示例。下面是OutputFactoryFactory的代码:

        public class OutputFactoryFactory{

               public static  OutputFactory  getOutputFactory(String type){

                       if(type.equalsIngnoreCase("better"){

                           return new BetterPrinterFactory();

                         }else{

                             return new PrinterFactory();

                         }

                  }

            }

        修改Computer类的Mian方法如下:

        public static void main(String[] args){

              outputFactory of =OutputFactoryFactory.getoutputFactory("better");

            Computer c = new Computer(of.getOutput());

            c.keyIn("轻量级java“);

            c.print();

        }

   上面程序中用于产生一个OutputFactory工厂,但具体产生哪个工厂则由OutputFactoryFactory抽象工厂决定,不同的工厂生产不同的output对象,通过采用抽象工厂模式,系统可以让客户端代码与被调用对象实现类、具体的工厂类实现分离。

     如果工厂直接生产被调用对象,那就是简单工厂模式,如果工厂生产了工厂对象,那就升级为抽象工厂模式。

猜你喜欢

转载自collegeyuan.iteye.com/blog/2274282
今日推荐