一个工厂的故事续集
随着行业的激烈竞争,低端电视机已经淘汰,存活下来的高端电视机品牌就那么2家了,分别是:华为、荣耀。而工厂已经垄断了所有品牌的电视机的生产,为了使工厂继续保持营业额的增长,这个时候,工厂的高层开了一个重要会议。最终定下了一个战略目标:决定在生产电视机的同时,将营业范围扩大为笔记本电脑、手机行业。
为了实现这个目标,厂长又找到了工程师小曾,让他提供设计方案。
小曾眉头深锁,一时间没有想到合适的方案,于是开始梳理现有的情况,目前总共有几家工厂:华为工厂、荣耀工厂,分别生产华为智慧屏、荣耀智慧屏。
经营范围包含:电视机、笔记本电脑、手机。这个很长一段时间是不会改变的,那么可以这样:
电视机标准:
public interface TV {
public void play();
}
具体电视机:
/**
* 华为电视机
* @author zherop
*/
public class HuaweiTV implements TV {
public void play() {
System.out.println("华为电视机播放...");
}
}
/**
* 荣耀电视机
* @author zherop
*/
public class HonorSmartTV implements TV {
public void play() {
System.out.println("ҫǻ...");
}
}
笔记本电脑标准:
public interface PC {
public void surfInternet();
}
具体笔记本电脑:
/**
* 华为笔记本
* @author zherop
*/
public class HuaweiPC implements PC {
public void surfInternet() {
System.out.println("华为笔记本上网...");
}
}
/**
* 荣耀笔记本
* @author zherop
*/
public class HonorPC implements PC {
public void surfInternet() {
System.out.println("荣耀笔记本上网...");
}
}
手机标准:
public interface SmartPhone {
public void call();
}
具体手机:
/**
* 华为智能机
* @author zherop
*/
public class HuaweiSmartPhone implements SmartPhone {
public void call() {
System.out.println("华为智能机拨打电话...");
}
}
/**
* 荣耀智能机
* @author zherop
*/
public class HonorSmartPhone implements SmartPhone {
public void call() {
System.out.println("荣耀智能手机拨打电话...");
}
}
工厂标准:
/**
* 工厂规范
* @author zherop
*/
public interface Factory {
/**
* 生产电视机
*
* @return
*/
public TV createTV();
/**
* 生产笔记本电脑
* @return
*/
public PC createPC();
/**
* 生产智能手机
* @return
*/
public SmartPhone createSmartPhone();
}
具体工厂:
/**
* 华为工厂
* @author zherop
*/
public class HuaweiFactory implements Factory {
public TV createTV() {
return new HuaweiTV();
}
public PC createPC() {
return new HuaweiPC();
}
public SmartPhone createSmartPhone() {
return new HuaweiSmartPhone();
}
}
/**
* 荣耀工厂
* @author zherop
*/
public class HonorFactory implements Factory {
public TV createTV() {
return new HonorSmartTV();
}
public PC createPC() {
return new HonorPC();
}
public SmartPhone createSmartPhone() {
return new HonorSmartPhone();
}
}
场景代码:
public class Client {
public static void main(String[] args) {
// 使用华为工厂,生产华为全系产品
Factory factory = new HuaweiFactory();
TV tv = factory.createTV();
tv.play();
PC pc = factory.createPC();
pc.surfInternet();
SmartPhone smartPhone = factory.createSmartPhone();
smartPhone.call();
}
}
如果后续,有其他新的品牌崛起,那么现在的设计还是可以完美支持,只需要新增该品牌的工厂来生产该品牌的电视机、笔记本电脑、手机即可。
然后,小曾将此套设计交给了厂长去实施。果然好使!
…
好几年过去了,小米品牌强势崛起,在经营范围下,厂长想生产小米的产品。于是又找到了小曾。小曾明白需求后,便说:“厂长莫慌,此事皆在掌控之中”。然后直接给出了应对之策。
新增小米品牌工厂:
/**
* @author zherop
*/
public class XiaomiFactory implements Factory {
public TV createTV() {
return new XiaomiTV();
}
public PC createPC() {
return new XiaomiPC();
}
public SmartPhone createSmartPhone() {
return new XiaomiSmartPhone();
}
}
新增小米电视机、笔记本、手机:
/**
* 小米电视机
* @author zherop
*/
public class XiaomiTV implements TV {
public void play() {
System.out.println("小米电视机播放...");
}
}
/**
* 小米笔记本
* @author zherop
*/
public class XiaomiPC implements PC {
public void surfInternet() {
System.out.println("小米笔记本上网...");
}
}
/**
* 小米智能机
* @author zherop
*/
public class XiaomiSmartPhone implements SmartPhone{
public void call() {
System.out.println("小米智能机拨打电话...");
}
}
场景类:
public class Client {
public static void main(String[] args) {
// Factory factory = new HuaweiFactory();
// 切换为小米工厂,生产小米全系产品
Factory factory = new XiaomiFactory();
TV tv = factory.createTV();
tv.play();
PC pc = factory.createPC();
pc.surfInternet();
SmartPhone smartPhone = factory.createSmartPhone();
smartPhone.call();
}
}
好了,至此故事完结,故事中就使用了抽象工厂模式,接下来,我们来看看抽象工厂模式。
定义
抽象工厂模式定义:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。
涉及的两个概念:
(1)产品等级结构
产品的继承结构。比如故事中的TV、HuaweiTV、HonorSmartTV、XiaomiTV就是一个产品等级结构,总共有3个产品等级结构:TV、PC、SmartPhone。
(2)产品族
由同一个工厂生产的,位于不同产品等级结构中的一组产品。比如故事中的HuaweiFactory生产的HuaweiTV、HuaweiPC、HuaweiSmartPhone就是一个产品族,总共有3个产品族:Huawei产品族、Honor产品族、Xiaomi产品族。
示意图:
涉及的角色:
- 抽象工厂(AbstractFactory)
用于声明创建抽象产品的方法,往往是定义一组方法。比如故事中的Factory接口,就定义了生成TV、PC、SmartPhone方法。 - 具体工厂(ConcreteFactory)
实现抽象工厂声明的方法,生成一组具体产品,这些产品构成一个产品族。比如故事中的HuaweiFactory、HonorFactory、XiaomiFactory。 - 抽象产品(AbstractProduct)
为每种产品声明接口,在抽象产品种定义了抽象业务方法。可以是接口或者抽象类。比如故事中的TV、PC、SmartPhone。 - 具体产品(ConcreteProduct)
实现了抽象产品所定义的业务方法。比如故事中的HuaweiTV、HuaweiPC、HuaweiSmartPhone。
类图:
适用场景
- 场景类不需要关心具体产品创建的细节,将对象的创建与使用解耦;
- 存在多个产品族,并且每次只会使用其中一个产品族;
- 属于同一个产品族的产品会一起被使用。
比较典型的场景有:创建在不同操作系统的图形环境下都可以运行的系统。
扩展
- 可以很方便地增加产品族,符合“开闭原则”。此外增加产品等级结构,需要修改所有工厂类,不符合“开闭原则”。
- 如果只存在一个产品等级结构,抽象工厂模式就退化为工厂方法模式。