java 工厂模式 抽象工厂模式的区别_结合实例分析简单工厂模式&工厂方法模式&抽象工厂模式的区别...

之前写过一篇关于工厂模式(Factory Pattern)的随笔,里面分析了简单工厂模式,但对于工厂方法和抽象工厂的分析较为简略。这里重新分析分析三者的区别,工厂模式是java设计模式中比较简单的一个设计模式,但很多地方都用到了工厂模式,(如解析xml中,jdbc连接数据库等)利用好工厂模式对程序的设计很有用处。工厂模式在一些设计模式的书中分为简单工厂模式,工厂方法模式和抽象工厂模式三类。也有把工厂方法模式划分到抽象工厂模式的,认为工厂方法是抽象工厂模式的特例的一种,就是只有一个要实现的产品接口。下面结合例子分析三者的区别。

首先是简单工厂模式,这里以工厂生产产品为例。

产品类的共同接口

1 packagefactory;2 /**

3 *4 *@authorCIACs5 *6 */

7 public interfaceProduct {8 //声明类所需继承的共同接口,也可以是抽象类

9 }

产品类A

1 packagefactory;2 /**

3 *4 *@authorCIACs5 *6 */

7 public class ProductA implementsProduct {8 publicProductA() {9 System.out.println("ProductA");10 }11 }

产品类B

1 packagefactory;2 /**

3 *4 *@authorCIACs5 *6 */

7 public class ProductB implementsProduct {8 publicProductB() {9 System.out.println("ProductB");10 }11 }

工厂类

1 packagefactory;2 /**

3 *4 *@authorCIACs5 *6 */

7 public classFactory {8 //可以在工厂类中添加任何你所需要的逻辑

9 public staticProduct create(String str)10 {11 //生成ProductA

12 if(str.equalsIgnoreCase("ProductA"))13 {14 return newProductA();15 }16 else

17 //生成ProductB

18 if(str.equalsIgnoreCase("ProductB"))19 {20 return newProductB();21 }22 return null;23 }24

25 }

客户端

1 packagefactory;2 /**

3 *4 *@authorCIACs5 *6 */

7 public classClient {8 public static voidmain(String[] args) {9 //调用Factory的静态方法生成所要的类

10 Factory.create("productA");11 Factory.create("ProductB");12 }13 }

控制台输出结果:

54ae9cae899eb6f4ef50757f41ffdf39.png

简单工厂模式实现了生成产品类的代码跟客户端代码分离,在工厂类中你可以添加所需的生成产品的逻辑代码,但是问题来了,优秀的java代码是符合“开放-封闭”原则的,也就是说对扩展开发,对修改关闭,如果你要加一个产品类C,你就要修改工厂类里面的生成产品的代码,在这里你就要增加if-else判断。对于这个问题,我们的工厂方法模式就可以解决这个问题。

接下来是工厂方法模式

产品类中增加了ProductC(其他产品类的代码是可以重用上面的,只要把包名更改了就行)。

1 packagefactoryMehtod;2 /**

3 *4 *@authorCIACs5 *6 */

7

8 public class ProductC implementsProduct {9 publicProductC() {10 System.out.println("productC");11 }12 }

声明工厂接口

1 packagefactoryMehtod;2 /**

3 *4 *@authorCIACs5 *6 */

7 public interfaceFactory {8 //声明产生产品类的方法

9 publicProduct createProduct();10 }

产生ProductA的FactoryA

1 packagefactoryMehtod;2 /**

3 *4 *@authorCIACs5 *6 */

7 public class FactoryA implementsFactory {8 //实现工厂类的方法生成产品类A

9 publicProduct createProduct()10 {11 return newProductA();12 }13

14 }

产生ProductB的FactoryB

1 packagefactoryMehtod;2 /**

3 *4 *@authorCIACs5 *6 */

7 public class FactoryB implementsFactory {8 //实现工厂类的方法生成产品类B

9 publicProduct createProduct()10 {11 return newProductB();12 }13 }

产生ProductC的FactoryC

1 packagefactoryMehtod;2 /**

3 *4 *@authorCIACs5 *6 */

7 public class FactoryC implementsFactory {8 //实现工厂类的方法生成产品类C

9 publicProduct createProduct()10 {11 return newProductC();12 }13 }

客户端

1 packagefactoryMehtod;2 /**

3 *4 *@authorCIACs5 *6 */

7 public classClient {8 public static voidmain(String[] args) {9 Factory factory;10 factory = newFactoryA();11 factory.createProduct();12 factory = newFactoryB();13 factory.createProduct();14 factory = newFactoryC();15 factory.createProduct();16 }17 }

控制台输出结果:

71bf9f87c4b99d56d9c62bd8ccf62d09.png

工厂方法模式中我们把生成产品类的时间延迟,就是通过对应的工厂类来生成对应的产品类,在这里我们就可以实现“开发-封闭”原则,无论加多少产品类,我们都不用修改原来类中的代码,而是通过增加工厂类来实现。但是这还是有缺点的,如果产品类过多,我们就要生成很多的工厂类。假如我们要实现的产品接口不止一个,也就是有多个产品接口,不同产品接口有对应的产品族。什么是产品族呢?简单的理解就是,不同牌子产的车里面会有跑车类型,家庭类型,商用类型等的车,不同牌子的车的跑车类型的车可以组成一个产品族。对于这种情况我们可以采用抽象工厂模式。

最后是抽象工厂模式,在这里我们为不同产品附加上对应的礼物,就是说ProductA中会有GiftA。

增加的Gift接口

1 packageabstractFactory;2 /**

3 *4 *@authorCIACs5 *6 */

7 public interfaceGift {8 //声明产品赠品的接口,当然也可以是抽象类,同样为了简单就不声明方法了

9 }

GiftA类

1 packageabstractFactory;2 /**

3 *4 *@authorCIACs5 *6 */

7 public class GiftA implementsGift {8 publicGiftA()9 {10 System.out.println("GiftA");11 }12 }

GiftB类

1 packageabstractFactory;2 /**

3 *4 *@authorCIACs5 *6 */

7 public class GiftB implementsGift {8 publicGiftB()9 {10 System.out.println("GiftB");11 }12 }

Factory接口

1 packageabstractFactory;2 /**

3 *4 *@authorCIACs5 *声明Product类工厂和Gift类工厂的工同工厂接口6 */

7 public interfaceFactory {8 publicProduct createProduct();9 publicGift createGift();10

11 }

生成ProductA和GiftA的FactoryA

1 packageabstractFactory;2 /**

3 *4 *@authorCIACs5 *FactoryA可以生成ProductA和GiftA6 */

7 public class FactoryA implementsFactory {8 @Override9 publicProduct createProduct()10 {11 return newProductA();12 }13 @Override14 publicGift createGift()15 {16 return newGiftA();17 }18 }

生成ProductB和GiftB的FactoryB

1 packageabstractFactory;2 /**

3 *4 *@authorCIACs5 *FactoryB可以生成ProductB和GiftB6 */

7 public class FactoryB implementsFactory {8 @Override9 publicProduct createProduct() {10 return newProductB();11 }12 @Override13 publicGift createGift() {14 return newGiftB();15 }16

17 }

客户端

1 packageabstractFactory;2 /**

3 *4 *@authorCIACs5 *6 */

7 public classClient {8 public static voidmain(String[] args) {9 Factory factory;10 factory = newFactoryA();11 factory.createProduct();12 factory.createGift();13 factory = newFactoryB();14 factory.createProduct();15 factory.createGift();16 }17 }

控制台输出结果:

0d7b66f7203917dc74cf13fa6b07e84e.png

抽象工厂模式中我们可以定义实现不止一个接口,一个工厂也可以生成不止一个产品类,抽象工厂模式较好的实现了“开放-封闭”原则,是三个模式中较为抽象,并具一般性的模式。我们在使用中要注意使用抽象工厂模式的条件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值