设计模式十二——抽象工厂模式

抽象工厂模式介绍

定义:提供一个创建一系列相关或互相依赖对象的接口,而无需指定他们具体的类。
暂且不管上面的定义,我们来分析一下抽象工厂模式和工厂模式的不同之处:
在工厂模式中我们为每一个抽象产品创建了一个抽象工厂,然后为每一个具体产品提供了一个具体工厂角色,这些具体工厂角色用于创建相应的具体产品对象。(工厂方法模式);
在抽象工厂模式中,不同点是我们为多个抽象产品创建了一个抽象工厂,为所有的具体产品提供了相应的具体工厂角色,但是这些具体工厂角色并不是如同工厂方法模式中一对一,而是一个具体工厂角色对多个具体产品,每一个具体工厂角色对应的是一个产品族的具体产品类。
产品族的概念:位于不同产品等级中,功能相关联产品组成的家族。
在这里插入图片描述
看到这里我们应该明白工厂方法模式和抽象工厂模式的最大不同是:工厂方法模式是针对一个产品等级结构的,而抽象工厂模式是针对多个产品等级结构的。

抽象工厂模式相关角色

角色功能
抽象产品角色是该等级产品结构中所有产品的一个抽象
具体产品角色继承了抽象产品角色,实现了具体产品应有的功能
抽象工厂角色是所有具体工厂角色的抽象,内部含有获取相应产品等级结构对象的抽象方法
具体工厂角色继承了具体工厂角色,每一个具体工厂角色实现了获取所有相应产品族对象的方法,一个具体工厂角色对应一个产品族

抽象工厂模式UML

在这里插入图片描述

案例

小明有一个衣柜,里面一共有两个隔间,第一个隔间里面是上衣,第二个隔间里面是裤子。其中上衣隔间中有短袖和大衣,第二个隔间中有短裤和秋裤。请使用抽象工厂模式帮小明分别在夏天和秋天选择他应该穿的衣服。

案例分析

在这个案例中产品的等级结构非常清楚,一共有两个产品等级结构或者说产品种类——上衣和裤子,其中上衣种类产品中有两个具体产品,裤子种类产品中有两个具体产品。现在我们来分析一下具体相应的角色应该包含哪些。
(1)抽象产品角色:有两个分别是ShangYi类和KuZi类
(2)具体产品角色:同样有两大类,继承ShangYi类的有短袖和大衣,继承KuZi类的有短裤和秋裤。
(3)抽象工厂角色:只有一个AbstractFactory类,是一个抽象类,内部包含了createShangYi方法和createKuZi方法。
(4)具体工厂角色:有两个分别是SummerSuit和AutumnSuit两个类,继承了AbstractFactory抽象类。
这样我们实现了使用一个抽象工厂服务多个抽象角色的功能,同时在每一个具体工厂中都含有返回对应产品族对象的方法。

案例实现

抽象产品角色
(1)抽象上衣类

package abstracted.factory.pattern;
/**
 * @Introduction 该类是一个上衣抽象类
 */
public abstract class ShangYi {
	public abstract void wearShangYi();
}

(2)抽象裤子类

package abstracted.factory.pattern;
/**
 * @Introduction 该类是一个裤子的抽象类
 */
public abstract class KuZi {
	public abstract void wearKuZi();
}

具体产品类

(1)具体短袖类

package abstracted.factory.pattern;
/**
 * @Introduction 该类是短袖类,继承了ShangYi抽象类
 */
public class Tshirt extends ShangYi{
	//重写穿上衣方法
	@Override
	public void wearShangYi() {
		System.out.println("上身穿短袖");
	}
}

(2)具体大衣类

package abstracted.factory.pattern;
/**
 * @Introduction 该类是大衣类,继承了ShangYi抽象类
 */
public class Overcoat extends ShangYi{
	//重写穿上衣方法
	@Override
	public void wearShangYi() {
		System.out.println("上身穿大衣");
	}
}

(3)具体短裤类

package abstracted.factory.pattern;
/**
 * @Introduction 该类是短裤类,继承了KuZi抽象类
 */
public class Shorts extends KuZi{
	//重写了穿裤子方法
	@Override
	public void wearKuZi() {
		System.out.println("下身穿短裤");
	}
}

(4)具体秋裤类

package abstracted.factory.pattern;
/**
 * @Introduction 该类是秋裤类,继承了KuZi抽象类
 */
public class LongPants extends KuZi{
	//重写了穿裤子方法
		@Override
		public void wearKuZi() {
			System.out.println("下身穿秋裤短裤");
		}
}

抽象工厂类

package abstracted.factory.pattern;
/**
 * @Introduction 该类是抽象工厂
 */
public abstract class AbstractFactory {
	public abstract ShangYi createShangYi();
	public abstract KuZi createKuZi();
}

具体工厂类
(1)夏装具体工厂类(就是使用一个具体工厂类来创建所有对应的产品族)

package abstracted.factory.pattern;
/**
 * @Introduction 该类是具体工厂类,是夏日套装类,继承了AbstractFactory抽象类,在该类内部对应的产品族为短裤和短袖
 */
public class SummerSuit extends AbstractFactory{
	//重写了创建上衣方法
	@Override
	public ShangYi createShangYi() {
		return new Tshirt();
	}
	//重写了创建裤子方法
	@Override
	public KuZi createKuZi() {
		return new Shorts();
	}
}

(2)秋装具体工厂类(使用一个秋装具体工厂类来创建所有求装的产品族)

package abstracted.factory.pattern;
/**
 * @Introduction 该类是具体工厂类,是秋日套装类,继承了AbstractFactory抽象类,在该类内部对应的产品族为秋裤和大衣
 */
public class AutumnSuit extends AbstractFactory{
	//重写了创建上衣方法
		@Override
		public ShangYi createShangYi() {
			return new Overcoat();
		}
		//重写了创建裤子方法
		@Override
		public KuZi createKuZi() {
			return new LongPants();
		}
}

模拟用户界面的调用该模式

package abstracted.factory.pattern;
/**
 * @Introduction 该类模拟用户界面,在用户界面调用相关具体工厂类来创建对应的对象
 */
public class Main {
	public static void main(String[] args) {
		AbstractFactory clothFactory;    //定义一个保存具体工厂对象的引用
		ShangYi shangyi;                 //小明穿的上衣类引用
		KuZi kuzi;                       //小明穿的裤子类引用
		
		//小明在夏天的套装
		clothFactory=new SummerSuit();
		shangyi=clothFactory.createShangYi();   //获取对应的对象(在这里实现了面对接口编程)
		kuzi=clothFactory.createKuZi();         //获取对应的裤子对象
		shangyi.wearShangYi();
		kuzi.wearKuZi();
		
		//小明在秋天放的套装
		clothFactory=new AutumnSuit();   
		shangyi=clothFactory.createShangYi();
		kuzi=clothFactory.createKuZi();
		shangyi.wearShangYi();
		kuzi.wearKuZi();
	}
}

运行的界面如下在这里插入图片描述

抽象工厂模式优缺点及使用场景

优点:

  1. 在用户界面实现了面对接口编程,增加了程序的拓展性
  2. 当我们需要增加一个产品族的时候,我们无需修改原有类的内部代码,只需要增加相应的类。

缺点:
如果我们需要增加一个新的产品等级(新加一种新的产品,比如在上面的案例中增加一个小明的鞋子类),我们需要修改抽象工厂角色、具体工厂角色中的代码,这不符合开放-封闭原则。

使用场景:

  1. 系统中有多个产品族,而每次用于只需要使用一套产品族
  2. 系统中用户不需要知道产品是如何创建
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值