1.工厂模式简介
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
⼯⼚模式有 3 种不同的实现⽅式:
① 简单⼯⼚模式(静态工厂):通过传⼊相关的类型来返回相应的类,这 种⽅式⽐较单 ⼀,可扩展性相对较差。
② ⼯⼚⽅法模式:通过实现类实现相应的⽅法来决定相应的返回结果,这种⽅式的可扩展性⽐较强。
③ 抽象⼯⼚模式:基于上述两种模式的拓展,且⽀持细化产品。
1.1.工厂模式——简单⼯⼚模式(静态工厂)
工厂模式思路如下
/*
* 设计模式之工厂模式
* 工厂模式实例分析
* 手机接口
* */
public interface Phone {
void phoneBrand();
}
Huawei手机类:(具体的产品A)
public class Huawei implements Phone {
public Huawei() {
this.phoneBrand();
}
@Override
public void phoneBrand() {
System.out.println("华为手机");
}
}
Xiaomi手机类:(具体的产品B)
public class Xiaomi implements Phone {
public Xiaomi() {
this.phoneBrand();
}
@Override
public void phoneBrand() {
System.out.println("小米手机");
}
}
手机工厂类:(抽象工厂)
public class PhoneFactory {
public Phone makePhone(String phonetype){
if (phonetype.equalsIgnoreCase("iphone")){
return new iphone();
}else if(phonetype.equalsIgnoreCase("Huawei")){
return new Huawei();
}else if(phonetype.equalsIgnoreCase("Xiaomi")){
return new Xiaomi();
}
return null;
}
}
测试类:
public class Test {
public static void main(String[] args) {
PhoneFactory phoneFactory = new PhoneFactory();
Phone iphone = phoneFactory.makePhone("iphone");
Phone xiaomi = phoneFactory.makePhone("Xiaomi");
Phone huawei = phoneFactory.makePhone("Huawei");
}
}
结果:
苹果手机
小米手机
华为手机
优点:
将对象的创建和对象本身业务处理分离可以降低系统的 耦合度,使得两者修改起来都相对容易。
缺点:
- ⼚类的职责相对过重,增加新的产品需要修改⼯⼚类的判断逻辑,这⼀点与开闭原则是相违背。
- 即开闭原则(Open Close Principle)对扩展开放,对修改关闭,程序需要进⾏拓展的时候,不能去修改原有的代码,实现⼀个热插拔的效果。
- 将会增加系统中类的个数,在⼀定程度上增加了系统的复杂度和理解难度,不利于系统的扩展和维护,创建简单对象就不⽤模式。
总结:
1.可以看出手机工厂类产生了各个不同品牌的手机,但是这种工厂模式是解耦性非常低的,当又增加一个手机品牌的时候,我们有需要重新在工厂类中添加if判断的逻辑代码,还需要添加一个新的品牌的实现类以及逻辑代码
2.如果还有更多,呢就需要依次添加下去
3.那么这就违背了⼯⼚类要遵循的开闭原则(Open Close Principle)(对扩展开放,对修改关闭,程序需要进⾏拓展的时候,不能去修改原有的代码,实现⼀个热插拔的效果),这样就导致,每次扩展功能的时候都需要添加新的逻辑,并且需要对工厂类进行修改,如果是真实复杂的业务,这就增加了成本。
1.2工厂模式——工厂方法模式
和简单工厂模式中工厂负责生产所有产品相比,工厂方法模式将生成具体产品的任务分发给具体的产品工厂,具体如下图
public interface PhonemakeFactory {
Phone FacctoryPhone();
}
华为手机工厂类:(具体A的实现工厂)
public class HuaweiFactory implements PhonemakeFactory {
@Override
public Phone FacctoryPhone() {
return new Huawei();
}
}
小米手机工厂类:(图中具体B的实现工厂)
public class XiaomiFactory implements PhonemakeFactory {
@Override
public Phone FacctoryPhone() {
return new Xiaomi();
}
}
测试:
public static void main(String[] args) {
HuaweiFactory huaweiFactory = new HuaweiFactory();
huaweiFactory.FacctoryPhone();
XiaomiFactory xiaomiFactory = new XiaomiFactory();
xiaomiFactory.FacctoryPhone();
}
结果:
生产华为手机
生产小米手机
工厂方法模式优点:
- 符合开闭原则,增加⼀个产品类,只需要实现其他具体的产品类和具体的⼯⼚类;
- 符合单⼀职责原则,每个⼯⼚只负责⽣产对应的产品;
工厂方法模式缺点:
- 增加⼀个产品,需要实现对应的具体⼯⼚类和具体产品类;
- 每个产品需要有对应的具体⼯⼚和具体产品类;
手机制作工厂类:(即图中的抽象工厂)
1.3工厂模式——抽象工厂方法模式
抽象⼯⼚⽅法模式是简单工厂模式 和工厂方法模式的整合升级版。抽象⼯⼚模式在 Spring 中应⽤得最为⼴泛的⼀种设计模式。
上面两种模式不管工厂怎么拆分抽象,都只是针对一类产品Phone(AbstractProduct),如果要生成另一种产品PC,应该怎么表示呢?
最简单的方式是把2中介绍的工厂方法模式完全复制一份,不过这次生产的是PC。但同时也就意味着我们要完全复制和修改Phone生产管理的所有代码,显然这是一个笨办法,并不利于扩展和维护。
抽象工厂模式通过在总的生产工厂中增加创建产品的接口,并在具体子工厂中实现新加产品的创建,当然前提是子工厂支持生产该产品。否则继承的这个接口可以什么也不干。
从上面类图结构中可以清楚的看到如何在工厂方法模式中通过增加新产品接口来实现产品的增加的。
生产Pc的接口:
public interface PC {
void PCbrand();
}
生产华为PC的类:
public class HuaweiPc implements PC {
public HuaweiPc() {
this.PCbrand();
}
@Override
public void PCbrand() {
System.out.println("生产华为电脑");
}
}
生产小米PC的类:
public class XiaomiFactory implements MakeFactory {
@Override
public Phone FacctoryPhone() {
return new Xiaomi();
}
@Override
public PC FactoryPc() {
return new HuaweiPc();
}
}
制造工厂:增加生产pc的接口
public interface MakeFactory {
//生产电脑的工厂
Phone FacctoryPhone();
//生产Pc的工厂
PC FactoryPc();
}
华为工厂:增加生产华为pc 的制作
public class HuaweiFactory implements MakeFactory {
@Override
public Phone FacctoryPhone() {
return new Huawei();
}
@Override
public PC FactoryPc() {
return new HuaweiPc();
}
}
小米工厂:增加生产小米pc 的制作
public class XiaomiFactory implements MakeFactory {
@Override
public Phone FacctoryPhone() {
return new Xiaomi();
}
@Override
public PC FactoryPc() {
return new HuaweiPc();
}
}
测试:
public static void main(String[] args) {
HuaweiFactory huaweiFactory = new HuaweiFactory();
huaweiFactory.FacctoryPhone();
huaweiFactory.FactoryPc();
XiaomiFactory xiaomiFactory = new XiaomiFactory();
xiaomiFactory.FacctoryPhone();
xiaomiFactory.FactoryPc();
}
结果:
生产华为手机
生产华为电脑
生产小米手机
生产华为电脑
- ⼯⼚⽅法模式引⼊⼯⼚等级结构,解决了简单⼯⼚模式中⼯⼚类职责过重的问题。
- 但⼯⼚⽅法模式中每个⼯⼚只创建⼀类具体类的对象,后续发展可能会导致⼯⼚类过多,因此将⼀些相关的具体类组成⼀个“具体类族”,由同⼀个⼯⼚来统⼀⽣产, 强调的是⼀系列相关的产品对象!!!
总结
抽象工厂模式是工厂方法模式的升级版,后者面向单个产品,而前者面向的的是一个产品族。根据官方定义:为创建一组相关/互相依赖的对象提供一个接口而无需指定它们的具体类。
比如一个汽车工厂要生成骑车,而每种汽车都有车门、车轮胎等一系列产品,这意味着每增加一款汽车就需要增加一个新的工厂来提供新产品的实现。这时候就可以使用抽象工厂模式来进行设计。抽象工厂模式适用于一系列产品族。
理解:
产品族:一个品牌下面的所有产品;例如华为下面的手机,路由器,电脑 称为华为的产品族;
产品等级:多个品牌下面的同种产品;例如华为和小米下面的手机 称为一个产品等级;