设计模式-工厂模式

工厂模式(Factory Pattern)

工厂模式(Factory Pattern):封装对象的创建,处理创建对象的细节。

工厂方法用来处理对象的创建,并将这样的行为封装在子类中。这样客户程序中超类的代码就和子类对象的创建部分解耦了

 

 

工厂方法分为:简单工厂(静态工厂)、工厂方法、抽象工厂。

几种方式的对比:

简单工厂vs工厂模式:

  简单工厂把全部的事情在一个地方做完了,而工厂模式是一个创建框架,让子类决定如何实现
抽象工厂vs工厂模式:
  抽象工厂的方法经常以工厂方法的方式实现,抽象工厂的任务是定义一个负责创建一组产品的接口。
  工厂方法使用继承,抽象工厂使用组合。
  工厂方法只是用来创建一种产品,而抽象工厂创建的是一个产品家族。
  使用工厂模式意味着需要扩展一个类并覆盖它的工厂方法。抽象工厂提供了一个创建产品家族的抽象类型,类型的子类定义了产品生产的方式。

简单工厂(静态工厂)结构:

简单工厂模式(Simple Factory Pattern):定义一个工厂类,根据不同的参数,创建并返回不同的类。其中这些类具有一个公共的父类或是一个接口。

 

 

 

 

Factory:工厂类,内部有是个精通的方法,根据参数选择创建的对象

Product:抽象产品类,其作为具体产品的父类,负责定义产品的公共接口

ConcreteProduct:具体产品类,有多个,都是继承与抽象产品类,工厂就是创建该类对象

//Product:Pizza抽象产品类
public abstract class Pizza{
    /*属性*/
    String name;
    String dough;
    String sauce;
    List<String> toppings = new ArrayList<String>();
    /*提供方法*/
    public String getName() {return name;}
    public void prepare() {System.out.println("Preparing " + name);}
    public void bake() {System.out.println("Baking " + name);}
    public void cut() {System.out.println("Cutting " + name);}
    public void box() {System.out.println("Boxing " + name);}
    public String toString() {
        StringBuffer display = new StringBuffer();
        display.append(name).append(dough ).append(sauce );
        toppings.stream().forEach(topping->{display.append(topping);});
        return display.toString();
    }
}
//Concrete:Pizza具体产品类
public class CheesePizza extends Pizza{
    public CheesePizza() {
        name = "Cheese Pizza";
        dough = "Regular Crust";
        sauce = "Marinara Pizza Sauce";
        toppings.add("Fresh Mozzarella");
        toppings.add("Parmesan");
    }
}
//Concrete:Pizza具体产品类
public class VeggiePizza extends Pizza{
    public VeggiePizza() {
        name = "Veggie Pizza";
        dough = "Crust";
        sauce = "Marinara sauce";
        toppings.add("Shredded mozzarella");toppings.add("Grated parmesan");toppings.add("Diced onion");toppings.add("Sliced mushrooms");toppings.add("Sliced red pepper");toppings.add("Sliced black olives");
    }
}
//Factory:Pizza工厂类
public class SimplePizzaFactory{
    public Pizza createPizza(String type){
        Pizza pizza = null;
        if("cheese"==type){
            pizza = new CheesePizza();
        }else if("veggie"==type){
            pizza = new VeggiePizza();
        }
        return pizza;
    }
}
//调用类
public class PizzaStore {
    //工厂类
    SimplePizzaFactory factory;
    //创建工厂类 通过构造方法传入
    public PizzaStore(SimplePizzaFactory factory) {
        this.factory = factory;
    }
    public Pizza orderPizza(String type) {
        Pizza pizza;
        //通过工厂类取得Pizza实例
        pizza = factory.createPizza(type);
        pizza.prepare();pizza.bake();pizza.cut();pizza.box();
        return pizza;
    }
}

 

 

工厂方法模式结构:

工厂方法模式:定义一个用来创建对象的接口,让子类决定实例化哪一个类,让子类决定实例化延迟到子类。

 

 

 

 

//商品抽象
public abstract class Pizza{
    /*属性*/
    String name;
    String dough;
    String sauce;
    List<String> toppings = new ArrayList<String>();
    /*提供方法*/
    public String getName() {return name;}
    public void prepare() {System.out.println("Preparing " + name);}
    public void bake() {System.out.println("Baking " + name);}
    public void cut() {System.out.println("Cutting " + name);}
    public void box() {System.out.println("Boxing " + name);}
    public String toString() {
        StringBuffer display = new StringBuffer();
        display.append(name).append(dough ).append(sauce );
        toppings.stream().forEach(topping->{display.append(topping);});
        return display.toString();
    }
}
//Pizza实现类
public class CheesePizza extends Pizza{
  //初始化 public CheesePizza() { name = "Cheese Pizza"; dough = "Regular Crust"; sauce = "Marinara Pizza Sauce"; toppings.add("Fresh Mozzarella");toppings.add("Parmesan"); } } //Pizza实现类 public class VeggiePizza extends Pizza{
  //初始化 public VeggiePizza() { name = "Veggie Pizza"; dough = "Crust"; sauce = "Marinara sauce"; toppings.add("Shredded mozzarella");toppings.add("Grated parmesan");toppings.add("Diced onion");toppings.add("Sliced mushrooms");toppings.add("Sliced red pepper");toppings.add("Sliced black olives"); } } //工厂接口 public interface PizzaFactory{ public Pizza createPizza(); } //CheesePizza工厂方法 public class CheesePizzaFactory implements PizzaFactory{ @Override public Pizza createPizza() { return new CheesePizza(); } } //VeggiePizza工厂方法 public class VeggiePizzaFactory implements PizzaFactory{ @Override public Pizza createPizza() { return new VeggiePizza(); } } //工厂方法的调用 public class PizzaStore { public Pizza orderVeggiePizza() { VeggiePizzaFactory veggiePizzaFactory = new VeggiePizzaFactory(); //通过工厂类取得Pizza实例 Pizza pizza = veggiePizzaFactory.createPizza(); pizza.prepare();pizza.bake();pizza.cut();pizza.box(); return pizza; } public Pizza orderCheesePizza() { CheesePizzaFactory cheesePizzaFactory = new CheesePizzaFactory(); //通过工厂类取得Pizza实例 Pizza pizza = cheesePizzaFactory.createPizza(); pizza.prepare();pizza.bake();pizza.cut();pizza.box(); return pizza; } }

 

抽象工厂模式结构:

 

 

 

 

AbstractFactory:抽象工厂角色,它声明了一组用于创建一种产品的方法,每一个方法对应一种产品,如上述类图中的AbstractFactory就定义了两个方法,分别创建产品A和产品B
ConcreteFactory:具体工厂角色,它实现了在抽象工厂中定义的创建产品的方法,生产一组具体产品,这饿产品构件成了一个产品种类,每一个产品都位于某个产品等级结构中,如上述类图中的ConcreteFactoryA和ConcreteFactoryB
AbstractProduct:抽象产品角色,为每种产品声明接口,如图中AbstractProductA、AbstractProductB
ConcreteProduct:具体产品角色,定义了工厂生产的具体产品对象,实现抽象产品接口声明的业务方法,如图中ConcreteProductA1、ConcreteProductA2、ConcreteProductB1、ConcreteProductB2

 

//AbstractProduct:抽象产品角色(显示器)
public abstract class Display{
    public String showMessage();
}
//ConcreteProduct:具体产品角色
public class LCDDisplay extends Display{
    @Override
    public String showMessage() {
        return "LCD Display";
    }
}
//具体产品角色
public class PDPDisplay extends Display{
    @Override
    public String showMessage() {
        return "PDP Display";
    }
}
//抽象产品角色(键盘)
public abstract class Keyboard{
    public void press();
}
//具体产品角色
public class HuaWeiKeyboard extends Keyboard{
    @Override
    public void press() {
        System.out.println("Huawei");
    }
}
//抽象工厂角色
public interface ComputerFactory{
    public Keyboard createKeyboard();
    public Display createDisplay();
}
//具体工厂角色
public class HuaweiComputerFactory implements ComputerFactory{
    @Override
    public Keyboard createKeyboard() {
        return new HuaWeiKeyboard();
    }
    @Override
    public Display createDisplay() {
        return new LCDDisplay();
    }
}
//具体工厂角色
public class OtherComputerFactory implements ComputerFactory{
    @Override
    public Keyboard createKeyboard() {
        return new HuaWeiKeyboard();
    }
    @Override
    public Display createDisplay() {
        return new PDPDisplay();
    }
}

  

 

设计原则:

1、依赖倒置原则

  不能让高层组件依赖底层组件,而且不管高层、底层组件,两者都应该依赖于抽象。

 

如何避免违反依赖倒置原则:

  ①变量不可以持有具体类的引用。

  如果使用new,则会持有具体类的引用,可以用工程来避开这样的做法

  ② 不要让类派生自具体类。

  如果派生自具体类,你就会依赖具体类(请派生自一个抽象类或接口)

  ③不要覆盖基类中已实现的方法。
  如果覆盖基类已实现的方法,那么你的基类就不是一个真正适合被继承的抽象。基类中已实现的方法,应该由所有的子类共享。

优点:

简单工厂模式优点:

  集中封装了对象的创建,使得要更换对象时不需要做大的改动就可实现,降低了客户端程序与产品对象的耦合。

  简单工厂模式最大的优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。 

 

工厂方法模式优点:

  集中封装了对象的创建,使得要更换对象时不需要做大的改动就可实现,降低了客户端程序与产品对象的耦合。

  工厂模式是简单工厂模式的进一步抽象和推广。它遵循了“开放—封闭”原则。         

 

抽象工厂模式优点:

  抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部对产品族进行约束。

  所谓的产品族,一般或多或少的都存在一定的关联,抽象工厂模式就可以在类内部对产品族的关联关系进行定义和描述,而不必专门引入一个新的类来进行管理。

缺点:

简单工厂模式缺点:

  是没有遵守开放—封闭原则。所谓的“开放-封闭”原则就是开放接口,封闭修改。

  如果将来需要添加一个开方的算法,那么,在简单工厂模式中,就必须在简单工厂类中添加相应的判断语句!

  另外,在简单工厂类中利用了Switch语句,这对程序的扩展本身就不不利。

 

工厂方法模式缺点:

  工厂方法把简单工厂的内部逻辑判断转移到了客户端代码来执行;

  每增加一产品就要增加一个产品工厂的类,增加了额外的开发量。

 

抽象工厂模式缺点:

  产品族的扩展将是一件十分费力的事情,假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改,对“开闭原则”的支持呈现倾斜性。

  所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。

应用场景:

消费者不关心它所要创建对象的类(产品类)的时候。

消费者知道它所要创建对象的类(产品类),但不关心如何创建的时候。

 

posted @ 2020-06-03 17:10  梦里前进  阅读(146)  评论(0编辑  收藏  举报