设计模式-工厂模式
工厂模式(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语句,这对程序的扩展本身就不不利。
工厂方法模式缺点:
工厂方法把简单工厂的内部逻辑判断转移到了客户端代码来执行;
每增加一产品就要增加一个产品工厂的类,增加了额外的开发量。
抽象工厂模式缺点:
产品族的扩展将是一件十分费力的事情,假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改,对“开闭原则”的支持呈现倾斜性。
所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。
应用场景:
消费者不关心它所要创建对象的类(产品类)的时候。
消费者知道它所要创建对象的类(产品类),但不关心如何创建的时候。

浙公网安备 33010602011771号