工厂模式分类
- 简单工厂:工厂里维护业务需要的全部对象,客户端请求时,工厂根据具体业务需求返回所需对象。缺点是增加新的业务对象,需要改判断逻辑,违反了开闭原则,客户端依赖工厂实现并不是依赖抽象违反了依赖倒置。
- 工厂方法模式:弥补了简单工厂设计上的缺陷。定义抽象工厂,每个业务实现对应一个工厂实例去生产对象。
- 抽象工厂模式:工厂方法模式每次只能生产同一产品统一零件的不同对象,比如不同汽车配不同发动机,可满足当前业务需求。当不同汽车需要不同发动机,且配置不同车标时,也就是汽车是一个由发动机和车标组成的产品组,工厂方法不能满足需求。这时用抽象工厂模式。
上代码
// 发动机
public interface Engine {
String getEngine();
}
// 大众发动机
public class DaZhongEngine implements Engine {
@Override
public String getEngine() {
return "大众发动机";
}
}
// 大奔发动机
public class DaBenEngine implements Engine {
@Override
public String getEngine() {
return "大奔发动机";
}
}
简单工厂
// 发动机工厂
public class EngineSimpleFactory {
public Engine getEngine(String wc) {
if ("dazhong".equals(wc)) {
return new DaZhongEngine();
} else if ("daben".equals(wc)) {
return new DaBenEngine();
}
return null;
}
}
// 客户端获取发动机
public static void main(String[] args) {
EngineSimpleFactory engineSimpleFactory = new EngineSimpleFactory();
Engine dazhong = engineSimpleFactory.getEngine("dazhong");
if (Objects.isNull(dazhong)) {
System.out.println("未找到对应的发动机");
return;
}
String engine = dazhong.getEngine();
System.out.println(engine);
}
简单工厂两个缺点
1.客户端依赖具体实现而非抽象接口,违背依赖倒置原则
2.增加新的发动机时,需要改factory的代码,违背开闭原则
工厂方法
发动机工厂抽象,为每种发动机建立不通工厂
// 发动机工厂抽象
public abstract class AbstractEngineFactory {
abstract Engine getEngineInstance();
}
// 大众发动机工厂抽象
public class DaZhongEngineFactory extends AbstractEngineFactory {
@Override
Engine getEngineInstance() {
return new DaZhongEngine();
}
}
// 大奔发动机工厂抽象
public class DaBenEngineFactory extends AbstractEngineFactory {
@Override
Engine getEngineInstance() {
return new DaBenEngine();
}
}
// 客户端
public static void main(String[] args) {
AbstractEngineFactory abstractEngineFactory = new DaBenEngineFactory();
System.out.println(abstractEngineFactory.getEngineInstance().getEngine());
AbstractEngineFactory abstractEngineFactory2 = new DaZhongEngineFactory();
System.out.println(abstractEngineFactory2.getEngineInstance().getEngine());
}
工厂方法解决了简单工厂的两个问题,每次新增发动机只需要新增对应的发动机工厂和发动机实体。
这时大众和大奔需要组装汽车,需要发动机的同时还需要车标,大众的发动机+大众车标组成大众汽车,工厂方法只能生产单个的零件对象,需要对设计升级一下工厂可以同时生产发动机和车标,就有了抽象工厂模式。
抽象工厂
定义车标log
//定义log接口
public interface Logo {
String getLogo();
}
public class DaBenLogo implements Logo {
@Override
public String getLogo() {
return "大奔车标";
}
}
public class DaZhongLogo implements Logo {
@Override
public String getLogo() {
return "大众车标";
}
}
//抽象汽车零件工厂
public abstract class AbstractCarFactory {
abstract Logo getLogoInstance();
abstract Engine getEngineInstance();
}
//大众汽车零件工厂
public class DaZhongCarFactory extends AbstractCarFactory {
@Override
Logo getLogoInstance() {
return new DaZhongLogo();
}
@Override
Engine getEngineInstance() {
return new DaZhongEngine();
}
}
//大奔汽车零件工厂
public class DaBenCarFactory extends AbstractCarFactory {
@Override
Logo getLogoInstance() {
return new DaBenLogo();
}
@Override
Engine getEngineInstance() {
return new DaBenEngine();
}
}
//客户端
public static void main(String[] args) {
AbstractCarFactory abstractCarFactory = new DaBenCarFactory();
Engine engineInstance = abstractCarFactory.getEngineInstance();
Logo logoInstance = abstractCarFactory.getLogoInstance();
System.out.println("开始组装大奔");
System.out.println(engineInstance.getEngine());
System.out.println(logoInstance.getLogo());
}