工厂模式属于创建模式,让类的创建交给工厂类,让工厂对象来决定具体创建哪一个实体类。
工厂模式分为抽象工厂模式与工厂方法模式,其应用场景也不相同,另外值得注意的是一个叫做“简单工厂”的模式,Head First设计模式中指出 简单工厂其实并不是一个设计模式,属于一种编程习惯,以为经常使用到所以被很多程序员误认为是工厂模式。但是不要以为并非严格的设计模式就去忽略它的用法。
简单工厂
我就按照Head First设计模式这本书中的例子来讲解吧。
假设我们开了一家披萨店,我们可能有芝士披萨,和风照烧披萨,水果披萨这三种类型的,那么我们肯定会去将披萨类设计成一个接口,或者是父类,在去更具具体的情况去实现它。更具不同的订单我们去制造不同的披萨
定义披萨接口
//定义一个披萨类接口
public interface Pizza {
//准备
public void prepare();
//烘焙
public void bake();
//切割
public void cut();
//包装
public void box();
}
定义一个工厂类
//定义工厂类 该类只有一个方法就是更具不同的类型生成不同口味的披萨
public class PizzaFactory {
//生成披萨
public static Pizza createPizza(String type) {
Pizza pizza=null;
if (type.equals("芝士披萨")) {
//这里的PizzaA,B,C定义的是pizza接口的实现类
pizza=new PizzaA();
}else if(type.equals("和风照烧")){
pizza=new PizzaB();
}else if(type.equals("水果披萨")){
pizza=new PizzaC();
}
return pizza;
}
}
定义一个披萨店
//披萨店
public class PizzaStore {
//客户订单
public Pizza PizzaOrder(String type) {
Pizza pizza=null;
//更具客户订单传入的参数来制造具体的披萨
pizza=PizzaFactory.createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();;
return pizza;
}
}
以上代码就是简单工厂的小案例,但是简单工厂有个缺点就是 不符合OCP原则,因为当我们需要添加新的口味的披萨的时候需要去在工厂类中去添加修改代码操作,所以我们有了工厂方法模式。(一般实际项目中大多是还是使用的简单工厂,想让简单工厂去符合ocp原则可以在去添加新的创建披萨方法即可)
工厂方法模式
定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。《菜鸟教程》
这里我们接着使用披萨店来举例,在披萨店开的火热风靡大江南北,这个时候我们开始去开分店,那么问题来了,不同的的确需要不同的口味,有些地区只喜欢吃甜的和海鲜,有的地区只喜欢吃辣的,这个时候我们考虑到每当有新的需求的时候就要去修改代码,这就是简单工厂的弊端,但是我们如果将工厂细分,再工厂抽象出来,这就可以解决OCP原则。
抽象工厂
public interface PizzaFactory {
//制作披萨
public Pizza createPizza(String type);
}
抽象产品类(披萨)
public interface Pizza {
//准备
public void prepare();
//烘焙
public void bake();
//切割
public void cut();
//包装
public void box();
}
实现产品类 此处省略实现方法。
public class PizzaA1 implements Pizza{}
public class PizzaA2 implements Pizza{}
public class PizzaB1 implements Pizza{}
public class PizzaB2 implements Pizza{}
实现工厂
public class PizzaFactoryA implements PizzaFactory{
@Override
public Pizza createPizza(String type) {
//这里就是创建具体的披萨类
Pizza pizza=null;
if (type.equals("霸王辣")) {
pizza=new PizzaA1();
}else if (type.equals("宇宙辣")) {
pizza=new PizzaA2();
}
return null;
}
}
public class PizzaFactoryB implements PizzaFactory {
@Override
public Pizza createPizza(String type) {
// 这里就是创建具体的披萨类
Pizza pizza = null;
if (type.equals("加糖芝士")) {
pizza = new PizzaA1();
} else if (type.equals("蜂蜜芝士")) {
pizza = new PizzaA2();
}
return null;
}
}
通过工厂方法模式我们解决了OCP原则问题,但是他同样也有新的问题,比如这个时候我们不只想买披萨,我们想和必胜客一样,还要卖汉堡,并且口味风格也要和地区一样,但是我们的工厂方法模式中专注的是一个产品,我们只做披萨 这个时候工厂方法模式就出现了局限性,所以抽象工厂模式出现了。
抽象工厂模式
抽象工厂可以理解为工厂方法模式的升级版,大致结构与抽象工厂模式相同 但是我们的抽象工厂提供了不同生成产品的方法
工厂方法模式主要关注点在于一个产品等级,而抽象工厂补全了这个缺点,画了一张图大家先理解一下
这里我就只写一点思路了,如果你理解了前面的工厂方法模式,那么按照这个思路 可以尝试着自己去写一下,实在想看代码的话就去其他博客看一下吧,重点还是在于理解这个设计思想。
- 抽象工厂类中定义 生产汉堡 和生产披萨的方法
- 抽象产品 定义一个汉堡 再定义一个披萨
- 更具产品来写工厂实现抽象工厂 每个工厂代表不同的地区 A地区喜欢芝士,B地区喜欢海鲜,C地区喜欢吃辣椒
- 实现方式和工厂方法模式大致
总结
工厂方法模式 :注重产品等级,类似于你在高中读书一样,不同的年级但是本质是相同的
抽象工厂模式 :工厂模式的升级版,可以生成出不同等级的不同产品。类似于大学,虽然年级相同,但是又不同的专业。