设计模式-抽象工厂模式
定义
抽象工厂模式提供了一个创建一系列相关或者相互依赖对象的接口,无需指定他们具体的类
适用场景
- 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
- 强调一系列相关的产品对象(属于同一产品族) 一起使用创建对象需要大量的重复代码
- 提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现
优点
- 具体产品在应用层的代码隔离,无需关心创建的细节
- 将一个系列的产品统一到一起创建
缺点
- 规定了所有可能被创建的产品集合,产品簇中扩展新的产品困难
- 增加了系统的抽象性和理解难度
代码实现
-
我们拿客户买手机和买笔记本举例,首先我们需要一个制作手机和笔记本的工厂,即产品的产品等级,所有的厂商制作手机和笔记本都得遵循这个规范:
// 制作手机 public interface PhoneProduct{ // 手机的开机功能 void switchOn(); // 手机的打电话功能 void call(); } ------------------------------------------------- // 制作笔记本 public interface LaptopProduct{ // 笔记本的开机功能 void switchOn(); // 用笔记本打游戏 void gaming(); }
-
有了这个工厂后我们假设有苹果和华为两个厂商,分别去做了这两个产品,即产品的产品族
// 苹果 public class ApplePhone implements PhoneProduct{ @Override public void switchOn(){ System.out.println("苹果手机开机"); } @Override public void call(){ System.out.println("苹果手机打电话"); } } public class AppleLaptop implements LaptopProduct{ @Override public void switchOn(){ System.out.println("苹果笔记本开机"); } @Override public void gaming(){ System.out.println("苹果笔记本打游戏"); } } --------------------------------------------- // 华为 public class HuaweiPhone implements PhoneProduct{ @Override public void switchOn(){ System.out.println("华为手机开机"); } @Override public void call(){ System.out.println("华为手机打电话"); } } public class HuaweiLaptop implements LaptopProduct{ @Override public void switchOn(){ System.out.println("华为笔记本开机"); } @Override public void gaming(){ System.out.println("华为笔记本打游戏"); } }
-
那么现在我们需要有一个抽象工厂,去约定是生产了什么东西,但具体怎么生产的,由谁生产,抽象工厂并不管
public interface ProductFactory{ // 生产手机 PhoneProduct phoneProduct(); // 生产笔记本电脑 LaptopProduct laptopProduct(); }
-
好了,到现在,我们可以知道,我们的生产工厂主要是生产了手机和笔记本电脑,而这个抽象的生产需要由具体的工厂去实现
public class AppleFactory implements ProductFactory{ // 生产苹果的手机 @Override public PhoneProduct phoneProduct(){ return new ApplePhone(); } // 生产苹果的笔记本 @Override public LaptopProduct laptopProdyct(){ return new AppleLaptop; } } ------------------------------------------ public class HuaweiFactory implements ProductFactory{ // 生产华为的手机 @Override public PhoneProduct phoneProduct(){ return new HuaweiPhone(); } // 生产华为的笔记本 @Override public LaptopProduct laptopProdyct(){ return new HuaweiLaptop; } }
-
到这一步,整个抽象工厂模式也就完成了,而客户只需要根据自己想要的需求找到对应的产品族及产品等级下的具体产品就行
public class Client{ public static void main(String[] args){ System.out.println("----------苹果产品-----------"); PhoneProduct iphone = new ApplePhone().phoneProduct(); LaptopProduct mac = new AppleLaptop().laptopProduct(); iphone.switchOn(); iphone.call(); mac.switchOn(); mac.gaming(); System.out.println("----------华为产品-----------"); PhoneProduct huaweiPhone = new HuaweiPhone().phoneProduct(); LaptopProduct huaLap = new HuaweiLaptop().laptopProduct(); HuaweiPhone.switchOn(); HuaweiPhone.call(); huaLap.switchOn(); huaLap.gaming(); } }
那么其实我们可以发现,在这种模式下,当我们需要添加一个厂商时,只需要添加实现该抽象工厂的厂商实现类就行,但是若我们想再添加一个生产的产品时,那么在下面的实现类下全都得再添加一个产品,这也是抽象工厂模式得缺点所在。