java设计模式-抽象工厂模式

模式导读:

        所谓抽象工厂模式就是它提供一个接口,用于创建相关或者依赖对象的家族,而不需要明确指定具体类,允许客户端使用抽象的接口来创建一组相关的产品,而不需要关系实际产出的具体产品是什么。这样一来,客户就可以从具体的产品中被解耦。它的优点是隔离了具体类的生成,使得客户端不需要知道什么被创建了,而缺点就在于新增新的行为会比较麻烦,因为当添加一个新的产品对象时,需要更改接口及其下所有子类。

参考类图

代码实现

 1.定义一个接口用于实现获取工厂内产品的方法

1 package com.etc;
2 
3 // 定义一个接口用于实现获取工厂内产品的方法
4 public interface AbstractComputerFactory {
5 
6      Computer getComputer(String msg);
7 
8 }
1 package com.etc;
2 
3 // 定义一个接口用于实现获取工厂内产品的方法
4 public interface AbstractPhoneFactory{
5 
6     Phone getPhone(String msg);
7 
8 }

2.定义具体的工厂类实现抽象工厂内获取具体产品的方法

(1)ComputerFactory.java

 1 package com.etc;
 2 
 3 //定义具体的工厂类实现抽象工厂内获取具体产品的方法
 4 public class ComputerFactory implements AbstractComputerFactory {
 5     // 根据用户需求给定产品
 6     public Computer getComputer(String msg) {
 7         if ("联想".equals(msg)) {
 8             return new LenovoComputer();
 9         } else if ("苹果".equals(msg)) {
10             return new AppleComputer();
11         }
12         return null;
13     }
14 
15 }

(2)PhoneFactory.java

 1 package com.etc;
 2 
 3 //定义具体的工厂类实现抽象工厂内获取具体产品的方法
 4 public class PhoneFactory implements AbstractPhoneFactory {
 5 
 6     public Phone getPhone(String msg) {
 7         if ("联想".equals(msg)) {
 8             return new LenovoPhone();
 9         } else if ("苹果".equals(msg)) {
10             return new ApplePhone();
11         }
12         return null;
13     }
14 
15 }

3.定义抽象产品类,里面定义获取具体产品信息的方法

(1)Computer.java

1 package com.etc;
2 
3 public interface Computer {
4     //定义一个接口实现产品电脑信息的打印
5     public void print();
6 
7 }

(2)Phone.java

1 package com.etc;
2 
3 public interface Phone {
4     //定义一个接口实现产品手机信息的打印
5     public void fill();
6 }

4.定义具体的产品实现类,里面实现打印出产品的信息的方法

(1)LenovoComputer.java

 1 package com.etc;
 2 
 3 public class LenovoComputer implements Computer {
 4 
 5     @Override
 6     public void print() {
 7         System.out.println("这是一台联想电脑!");
 8     }
 9 
10 }

(2)LenovoPhone.java

 1 package com.etc;
 2 
 3 public class LenovoPhone implements Phone {
 4 
 5     @Override
 6     public void fill() {
 7         System.out.println("这是一部联想手机!");
 8     }
 9 
10 }

(3)ApplePhone.java

 1 package com.etc;
 2 
 3 public class ApplePhone implements Phone {
 4 //工厂内具体产品苹果手机打印
 5     @Override
 6     public void fill() {
 7         System.out.println("这是一部苹果手机!");
 8     }
 9 
10 }

(4)AppleComputer.java

 1 package com.etc;
 2 
 3 public class AppleComputer implements Computer{
 4 
 5     @Override
 6     public void print() {
 7         System.out.println("这是一台苹果电脑!");
 8     }
 9 
10 }

5.定义一个类用于实现根据用户具体需求获取哪一个工厂

 1 package com.etc;
 2 
 3 //获得指定工厂
 4 public class Producer {
 5 
 6     private static AbstractPhoneFactory phoneFactory = null;
 7     private static AbstractComputerFactory computerFactory = null;
 8 
 9     private Producer() {
10 
11     }
12 
13     // 获得手机工厂
14     public static AbstractPhoneFactory getPhoneFactory() {
15         phoneFactory = new PhoneFactory();
16         return phoneFactory;
17     }
18 
19     // 获得电脑工厂
20     public static AbstractComputerFactory getComputerFactory() {
21         computerFactory = new ComputerFactory();
22         return computerFactory;
23     }
24 }

6.定义一个测试类

 1 package com.etc;
 2 
 3 public class Test {
 4 
 5     public static void main(String[] args) {
 6         // 用户需要电脑,且具体产品为苹果电脑
 7         Producer.getComputerFactory().getComputer("苹果").print();
 8         // 用户需要手机,且具体产品为联想手机
 9         Producer.getPhoneFactory().getPhone("联想").fill();
10 
11     }
12 
13 }

效果截图

抽象工厂模式优缺点:

优点:

当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

缺点:

产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。

适用场景:
1.系统不依赖于产品类实例如何被创建,组合和表达的细节。
2.系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
3.同属于同一个产品族是在一起使用的。这一约束必须在系统的设计中体现出来。
4.系统提供一个产品类的库,所有产品以同样的接口出现,从而使客户端不依赖于实现。

 

 

posted @ 2019-04-14 16:09  无影云  阅读(581)  评论(0编辑  收藏  举报