美文网首页
Design Patterns——Builder 模式、原型模式

Design Patterns——Builder 模式、原型模式

作者: Haraway | 来源:发表于2016-11-15 14:51 被阅读0次

    Design Patterns

    github地址:https://github.com/XieXiePro/PatternDemo

    一、Builder 模式

    将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以构建不同的表示。

    Builder模式的使用场景:

    (1)相同的方法,不同的执行顺序,产生不同的事件结果时。

    (2)多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不同时。

    (3)产品类非常复杂,或者产品类中的调用顺序不同产生了不同的作用,这个时候使用建造者模式非常合适。

    (4)当初始化一个对象特别复杂,如参数多,且很多参数都有默认值时。

    二、原型模式

    用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。

    原型模式的使用场景:

    (1)类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等,通过原型拷贝避免这些消耗。

    (2)通过new产生一个对象需要非常繁琐的h数据准备或者访问权限,这时可以使用原型模式。

    (3)一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用,即保护性拷贝。

    三、工厂模式

    定义一个用于创建对象的接口,让子类决定实例化哪个类。

    工厂模式的使用场景:

    在任何需要生成复杂对象的地方,都可以使用工厂方法。复杂对象适合使用工厂模式,用new就可以完成创建的对象无需使用工厂模式。

    工厂模式通用模式代码:

    /**
    * 抽象产品类
    */
    public abstract class Product{
      /**
      * 产品的抽象类
      * 由具体产品去实现
      */
      public abstract void method();
    }
    
    /**
    * 具体产品类A
    */
    public class ConcreteProductA extends Product{
     @override
      public void method(){
        System.out.println("我是具体的产品A");
      }
    }
    
    /**
    * 具体产品类B
    */
    public class ConcreteProductB extends Product{
     @override
      public void method(){
        System.out.println("我是具体的产品B");
      }
    }
    
    /**
    * 抽象工厂类
    */
    public abstract class Factory{
      /**
      * 抽象工厂方法
      * 具体生产什么由子类去实现
      * @return 具体的产品对象
      */
      public abstract Product createProduct();
    }
    
    /**
    * 具体工厂类
    */
    public class ConcreteFactory extends Factory{
     @override
      public Product createProduct(){
        return new ConcreteProductA();
      }
    }
    
    /**
    * 客户类
    */
    public class Client{
      public static void main(String[] args){
        Factory factory =new ConcreteFactory();
        Product p = factory.createProduct();
        p.method();
      }
    }
    
    

    这里的几个角色都很简单,主要分为四大模块,一是抽象工厂,其为工厂方法模式的核心;二是具体工厂,其实现了具体的业务逻辑;三是抽象产品,是工厂方法模式所创建的产品的父类;四是具体产品,为实现抽象产品的某个具体产品的对象。

    上述的代码中我们在Client类中构造了一个工厂抽象,并通过其生产了一个产品对象,这里我们得到的产品对象是ConcreteProductA的实例,如果想得到ConcreteProductB的实例,更改ConcreteFactory中的逻辑即可:

    public class ConcreteFactory extends Factory{
     @override
      public Product createProduct(){
        return new ConcreteProductB();
        //return new ConcreteProductA();
      }
    }
    

    这种方式n比较常见,需要哪一个产品就生产哪一个,有时候也可以利用反射的方式更简洁的来生产具体产品对象,此时,需要d在工厂方法的参数列表中传入一个Class类来决定是哪一个产品类:

    public abstract class Factory{
      /**
      * 抽象工厂方法
      * 具体生产什么由子类去实现
      *
      * @param clz 产品对象类类型
      *
      * @return 具体的产品对象
      */
      public abstract <T extends Product> T createProduct(Class<T> clz);
    }
    

    对于具体的工厂类,则通过反射获取类的示例即可:

    public class ConcreteFactory extends Factory{
     @override
      public <T extends Product> T createProduct(Class<T> clz){
        Product p = null;
        try{
          p = (Product)Class.forName(clz.getName()).newInstance();
        }catch(Exception e){
          e.printStackTrace();
        }
        return (T)p;
      }
    }
    

    最后再看看Client中的实现:

    public class Client{
      public static void main(String[] args){
        Factory factory =new ConcreteFactory();
        Product p = factory.createProduct(ConcreteProductB.class);
        p.method();
      }
    }
    

    需要哪一个类的对象就传入哪一个类的类型即可,这种方法比较简洁、动态,也可以尝试为每一个产品都定义一个具体的工厂,各司其职:

    public class ConcreteFactoryA extends Factory{
     @override
      public Product createProduct(){
        return new ConcreteProductA();
      }
    }
    
    public class ConcreteFactoryB extends Factory{
     @override
      public Product createProduct(){
        return new ConcreteProductB();
      }
    }
    
    public class Client{
      public static void main(String[] args){
        Factory factoryA =new ConcreteFactoryA();
        Product productA = factoryA.createProduct();
        productA.method();
        
        Factory factoryB =new ConcreteFactoryB();
        Product productB = factoryB.createProduct();
        productB.method();
      }
    }
    

    像这样拥有多个工厂的f方式我们称为多工厂方法模式。

    当我们的工厂只有一个的时候,我们还是为工厂提供了一个抽象类,如果确定你的工厂类只有一个,那么简化掉抽象类是肯定没问题的,我们只需要将对应的工厂方法改为静态方法即可:

    public class Factory{
      public static Product creteProduct(){
        return new ConreteProductB();
      }
    }
    

    像这样的方式称为简单工厂模式或静态工厂模式,它是工厂方法模式的一个弱化版本。

    四、抽象工厂模式

    为创建一组相关或者是相互依赖的对象提供一个接口,而不需要指定它们的具体类。

    抽象工厂模式的使用场景:

    一个对象族有相同的约束时可以使用抽象工厂模式。

    抽象工厂模式通用模式代码:

    /**
    * 抽象产品类A
    */
    public abstract class AbstractProductA{
      /**
      * 每个具体的产品子类需要实现的方法
      */
      public abstract void method();
    }
    /**
    * 抽象产品类B
    */
    public abstract class AbstractProductB{
      /**
      * 每个具体的产品子类需要实现的方法
      */
      public abstract void method();
    }
    /**
    * 具体产品类A1
    */
    public class ConcreteProductA1 extends AbstactProductA{
      @override
      public abstract void method(){
      System.out.println("具体产品A1的方法");
      }
    }
    /**
    * 具体产品类A2
    */
    public class ConcreteProductA2 extends AbstactProductA{
      @override
      public abstract void method(){
      System.out.println("具体产品A2的方法");
      }
    }
    /**
    * 具体产品类B1
    */
    public class ConcreteProductB1 extends AbstactProductA{
      @override
      public abstract void method(){
      System.out.println("具体产品B1的方法");
      }
    }
    /**
    * 具体产品类B2
    */
    public class ConcreteProductB2 extends AbstactProductA{
      @override
      public abstract void method(){
      System.out.println("具体产品B2的方法");
      }
    }
    /**
    * 抽象工厂类
    */
    public abstract class AbstractFactory{
      /**
      * 创建产品A的方法
      *
      * @return 产品A对象
      */
      public abstract AbstractProductA createProductA();
       /**
      * 创建产品B的方法
      *
      * @return 产品B对象
      */
      public abstract AbstractProductB createProductB();
    }
    /**
    * 具体工厂类1
    */
    public class ConcreteFactory1 extends AbstractFactory{
      @override
      public AbstractProductA createProductA(){
        return new ConcreteProductA1();
      }
      @override
      public AbstractProductB createProductB(){
        return new ConcreteProductB1();
      }
    }
    /**
    * 具体工厂类2
    */
    public class ConcreteFactory2 extends AbstractFactory{
      @override
      public AbstractProductA createProductA(){
        return new ConcreteProductA2();
      }
      @override
      public AbstractProductB createProductB(){
        return new ConcreteProductB2();
      }
    }
    

    虽然抽象工厂方法模式的类繁多,但是,主要还是分为4类。

    AbstractFactory:抽象工厂角色,它声明了一组用于创建一个产品的方法,每个方法对应一种产品。

    ConcreteFactory:具体工厂角色,它实现了抽象工厂中定义的创建产品的方法,生成一组具体产品,这些产品构成了一个产品种类,每一个产品都位于某个产品等级结构中。

    AbstractProduct:抽象产品角色,它为每种产品声明接口。

    ConcreteProduct:具体产品角色,它定义具体工厂生产的具体产品对象,实现抽象产品中声明的业务方法。

    虽然抽象工厂方法模式的类繁多,但是,主要还是分为4类。

    AbstractFactory:抽象工厂角色,它声明了一组用于创建一个产品的方法,每个方法对应一种产品。

    ConcreteFactory:具体工厂角色,它实现了抽象工厂中定义的创建产品的方法,生成一组具体产品,这些产品构成了一个产品种类,每一个产品都位于某个产品等级结构中。

    AbstractProduct:抽象产品角色,它为每种产品声明接口。

    ConcreteProduct:具体产品角色,它定义具体工厂生产的具体产品对象,实现抽象产品中声明的业务方法。

    五、策略模式

    策略模式定义了一系列算法,并将每一个算法封装起来,而且使用它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

    策略模式的使用场景:

    *针对同一类型问题的多种处理方式,仅仅是具体行为有差别时。

    *需要安全的封装多种同一类型的操作时。

    *出现同一抽象类有多个子类,而又需要使用if-else或者switch-case来选择具体子类时。

    相关文章

      网友评论

          本文标题:Design Patterns——Builder 模式、原型模式

          本文链接:https://www.haomeiwen.com/subject/mmtlpttx.html