设计模式-抽象工厂模式
1 简介
抽象工厂模式-顾名思义就是创建工厂的工厂,属于创建型模式,适用于一类产品有多个厂商这种情况。
1.1 适用场景
场景一: 一个系统中需要上传图片和视频至云平台,为此提供了七牛云、阿里云两种平台可以上传,这种场景下就可以使用抽象工厂模式进行开发。
场景二: 一款国王类游戏平台,有精灵王国、兽人王国,这两个王国都有城堡、军队、国王角色;王国的创建就可以使用抽象工厂模式。
1.2 优缺点
优点: 调用者不需要关注具体实现类,在调用时只需要创建对应的工厂类即可。
缺点: 产品族扩展非常困难,比如王国需要增加护城河,所有的接口和实现类都需要改动,违背了单一职责原则。
1.3 结构
- 抽象工厂(Abstact Factory):定义了一个创建产品族的接口,声明一系列创建不同产品的方法。
- 具体工厂(Concrete Factory):实现了抽象工厂接口,负责生成一个或多个具体产品族的产品对象。
- 抽象产品(Abstract Product):定义了产品族中每种产品的公共接口,是所有具体产品类的基类或接口。
- 具体产品(Concrete Product):实现了抽象产品接口,是产品族中每类产品的具体实现。
- 客户端(Client):通过调用具体工厂的接口来创建所需的产品对象,无需直接实例化具体产品类。
2 示例
以精灵王国和兽人王国为例,代码结构图如下:
2.1 创建抽象接口
- Army
public interface Army {
String getDescription();
}
- Castle
public interface Castle {
String getDescription();
}
- King
public interface King {
String getDescription();
}
2.2 实现具体产品
上述定义接口的实现类,为了方便区分,分别把精灵的实现类和兽人的实现类放在两个package下面
精灵王国的实现类如下:
- ElfArmy
public class ElfArmy implements Army {
@Override
public String getDescription() {
return "这是精灵王国的军队。。。";
}
}
- ElfCastle
public class ElfCastle implements Castle {
@Override
public String getDescription() {
return "这是精灵的城堡。。。";
}
}
- ElfKing
public class ElfKing implements King {
@Override
public String getDescription() {
return "精灵王国的国王。。。";
}
}
兽人王国的实现类:
- OrcArmy
public class OrcArmy implements Army {
@Override
public String getDescription() {
return "这是兽人王国的军队。。。";
}
}
- OrcCastle
public class OrcCastle implements Castle {
@Override
public String getDescription() {
return "这是兽人的城堡。。。";
}
}
- OrcKing
public class OrcKing implements King {
@Override
public String getDescription() {
return "精灵兽人的国王。。。";
}
}
2.3 定义抽象工厂
- KingdomFactory
public interface KingdomFactory {
Army createArmy();
Castle createCastle();
King createKing();
}
2.4 定义具体工厂
精灵王国具体工厂
- ElfKingdomFactory
public class ElfKingdomFactory implements KingdomFactory {
@Override
public Army createArmy() {
return new ElfArmy();
}
@Override
public Castle createCastle() {
return new ElfCastle();
}
@Override
public King createKing() {
return new ElfKing();
}
}
兽人王国具体工厂
- OrcKingdomFactory
public class OrcKingdomFactory implements KingdomFactory {
@Override
public Army createArmy() {
return new OrcArmy();
}
@Override
public Castle createCastle() {
return new OrcCastle();
}
@Override
public King createKing() {
return new OrcKing();
}
}
2.5 客户端调用
- App
public class App {
public static void main(String[] args) {
KingdomFactory factory = new OrcKingdomFactory();
Army army = factory.createArmy();
Castle castle = factory.createCastle();
King king = factory.createKing();
System.out.println(army.getDescription());
System.out.println(castle.getDescription());
System.out.println(king.getDescription());
}
}
3 抽象工厂的优缺点
3.1 优点
- 客户端调用面向接口,不需要关注具体实现
- 新增产品容易,符合开闭原则
3.2 缺点
- 产品族扩展麻烦,且会破坏单一职责原则,比如上述例子每个王国新增创建护城河角色,所有现有的接口和实现类都需要修改。
4 参考引用
示例中代码来自于:https://github.com/iluwatar/java-design-patterns