美文网首页
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