概念理解
工厂模式是一种创建型模式,统一创建对象,供客户端使用。客户端仅需从工厂中取对象,而不用关心创建对象的逻辑。
实例描述
以西餐厅制作披萨为例,西餐厅目前提供披萨种类有cheese pizza,pepper pizza,bacon pizza,点餐系统需要根据客户要求不同,制作不同的pizza。
直接实现:
在不使用任何模式的情况下,类的结构大致是这样的

public abstract class Pizza {
private String name ;
public Pizza(String name){
this.name = name;
}
public abstract void prepare();
public void bake(){
System.out.println(name+" is baked");
}
public void cut(){
System.out.println(name+" is cut");
}
public void box(){
System.out.println(name+" is boxed");
}
public String getName() {
return name;
}
}
public class BaconPizza extends Pizza {
public BaconPizza(){
super("baconPizza");
}
@Override
public void prepare() {
System.out.println(getName()+"is prepared");
}
}
public class RestaurantClient {
public void createPizza(String type){
Pizza pizza = null;
if("cheese".equals(type)){
pizza = new CheesePizza();
}else if ("bacon".equals(type)){
pizza=new BaconPizza();
}else if("pepper".equals(type)){
pizza=new PepperPizza();
}
if(pizza !=null){
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
}
}
}
缺点:这种直接的结构是客户端以if else的方式创建不同类,客户端必须关注类是如何创建的,如果新加入一个新的品种,客户端需要重新改造代码,加入新的品种。这种紧耦合的方式,违背了开放封闭原则。
设计一:简单工厂模式
简单工厂模式仅仅是把变化的部分独立出来,客户端仅需要关注业务,无需关注对象是如何创建的。

public class PizzaFactory {
public static Pizza createPizza(String type){
Pizza pizza = null;
if("cheese".equals(type)){
pizza = new CheesePizza();
}else if ("bacon".equals(type)){
pizza=new BaconPizza();
}else if("pepper".equals(type)){
pizza=new PepperPizza();
}
return pizza;
}
}
public class RestaurantClient {
public void productPizza(String type){
Pizza pizza = PizzaFactory.createPizza(type);
if(pizza !=null){
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
}
}
}
优点:将创建对象的功能独立出来,客户端仅需关注业务,无需关注对象的创建逻辑
缺点:工厂类中包含了所有类的创建,违反了高内聚的单一职责原则,不利于扩展。
设计二:工厂方法模式
避免简单工厂模式的缺点,核心工厂抽象为一个接口,将对象实例化交给具体工厂子类,核心工厂仅给出创建必须实现的接口,不再关注对象的具体实例化逻辑。具体工厂各司其职,给出具体的创建对象逻辑。

public interface IPizzaFactory {
Pizza createPizza();
}
public class BaconPizzaFactory implements IPizzaFactory {
@Override
public Pizza createPizza() {
return new BaconPizza();
}
}
public class RestaurantClient {
public void createPizza(String type){
IPizzaFactory factory =null;
if("cheese".equals(type)){
factory = new CheesePizzaFactory();
}else if ("bacon".equals(type)){
factory=new BaconPizzaFactory();
}else if("pepper".equals(type)){
factory=new PepperPizzaFactory();
}
Pizza pizza = factory.createPizza();
if(pizza !=null){
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
}
}
}
设计三
当西餐厅加入了新的产品类别-饮料时,就用到了抽象工厂模式。抽象工厂管理了多个品类的抽象创建方法,同时设计一个工厂构造器来创建具体的工厂。

public interface IFactory {
Pizza createPizza();
Drink createDrink();
}
public class BaconFactory implements IFactory{
@Override
public Pizza createPizza() {
return new BaconPizza();
}
@Override
public Drink createDrink() {
return new OrangeDrink();
}
}
public class FactoryCreator {
public static IFactory createFactory(String type){
IFactory factory = null;
if("cheese".equals(type)){
factory = new CheeseFactory();
}else if ("bacon".equals(type)){
factory=new BaconFactory();
}else if("pepper".equals(type)){
factory=new PepperFactory();
}
return factory;
}
}
public class RestaurantClient {
public void createPizza(String type){
IFactory factory =FactoryCreator.createFactory(type);
Pizza pizza = factory.createPizza();
if(pizza !=null){
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
}
Drink drink = factory.createDrink();
if(drink!=null){
drink.prepare();
drink.box();
}
}
}
注意点
曾经对工厂方法模式和抽象工厂模式的概念理解模糊不清,这里记录一下:
工厂方法模式是抽象工厂模式一个特例。
工厂方法模式适用于单一品类的工厂实例创建,抽象工厂适用于多种品类的工厂实例创建,两种适用场景不同
可以通过反射来构造不同的工厂对象,这样扩展时不要修改工厂构造器,改造后实例如下
public static IFactory createFactory(Class<? extends IFactory> clazz) throws IllegalAccessException, InstantiationException {
if(clazz !=null){
IFactory factory =clazz.newInstance();
return factory;
}
return null;
}
具体实例参见:https://github.com/jxl198/designPattern/tree/master/factory
网友评论