07、工厂模式-抽象工厂模式

先吐槽下,学习工厂模式时候,开始的时候都很恶心,但是反复的研究,明白后,并写出来后,才发现,真的值。
现在开始正式进入抽象工厂模式的学习和了解。
结合 工厂方法模式中所举的例子,为了更好的理解抽象工厂模式,我们把例子稍微调整下,不再以中国人外国人不能举例子,不是说不能用这个中国人外国人的例子,而是我发现有更好的例子。
我们换做汽车的例子来举例,首先 定义抽象类Car,然后用派生出子抽象类 ,SportCar,BusinessCar,分别是 跑车和商务车,派生出来的子类还是抽象类,因为还有如下:SportBenzCar( 奔驰跑车),BusinessBenzCar( 奔驰商用 ),SportBuickCar,BusinessBuickCar(此处需要想想,为什么抽象类Car的直接子类是SportCar和BusnessCar,然后这两个类的子类才是Benz和Buick,而不是Car的直接子类是BenzCar和BuickCar),所以来吧,先把几个抽象类和具体实现类给搞定, 具体的类如下:


代码实现如下:(几个文件的内容全都放在一起了)
   
  1. //定义车抽象产品,用途只体现在多态,客户端用此定义产品对象,子类或者子类工厂类实例化
  2. public abstract class Car {
  3. public abstract void desc();
  4. }
  5. //Car派生的子类,还是抽象产品,包含跑车和商务车
  6. public abstract class SportCar extends Car {}
  7. public abstract class BusinessCar extends Car {}
  8. //接下来不同品牌对两种车型的实现
  9. public class SportBenzCar extends SportCar {
  10. public void desc() {
  11. System.out.println("哥就是传说中的奔驰跑车!");
  12. }
  13. }
  14. public class BusinessBenzCar extends BusinessCar {
  15. public void desc() {
  16. System.out.println("奔驰商务车,成功人士的选择");
  17. }
  18. }
  19. public class SportBuickCar extends SportCar {
  20. public void desc() {
  21. System.out.println("本少即别克跑车!");
  22. }
  23. }
  24. public class BusinessBuickCar extends BusinessCar {
  25. public void desc() {
  26. System.out.println("商用别克,让您快乐");
  27. }
  28. }
以上是对产品的抽象类和具体类的编写,之后,我们模拟下,客户买车的环节的步骤:
1、进入一家4S店(或者是随便进一家,或者是指定的进入一家)
2、选择车类型(要么是自己心里有喜欢的车型了,或者是听4S店销售介绍)
那么问题来了,这个4S店怎么在我们的程序中体现?4S店开始有很多的,有宝马4S,福特4S,奔驰4S,别克4S等等,但是相同的是,每家4S店都是可以出售各种类型的,这样以来,我们还需要对4S店进行抽象,如下:
   
  1. //抽象4S店
  2. public abstract class SaleCar4S {
  3. public abstract SportCar choiceSport();
  4. public abstract BusinessCar choiceBusiness();
  5. //只是举了两个例子,可能还会包含 房车,越野车,甲壳虫等等车型
  6. }
  7. //奔驰4S店
  8. public class Benz4S extends SaleCar4S {
  9. public SportCar choiceSport() {
  10. return new SportBenzCar();
  11. }
  12. public BusinessCar choiceBusiness() {
  13. return new BusinessBenzCar();
  14. }
  15. }
  16. //别克4S店
  17. public class Buick4S extends SaleCar4S {
  18. public SportCar choiceSport() {
  19. return new SportBuickCar();
  20. }
  21. public BusinessCar choiceBusiness() {
  22. return new BusinessBuickCar();
  23. }
  24. }
好了,现在可以写客户端代码了,客户端代码是按照我们刚刚的买车步骤来的:
   
  1. public class Start {
  2. public static void main(String[] args) {
  3. //购车客户走进了一家卖车的4S店,一看是奔驰的4S店
  4. SaleCar4S _4S = new Benz4S();
  5. //然后 从这个4S店里面找了一款商用车
  6. Car c = _4S.choiceBusiness();
  7. //这款商务车的广告
  8. c.desc();
  9. //客户嫌广告词太老,不喜欢,于是重新选择了一辆跑车
  10. c = _4S.choiceSport();
  11. //这款跑车的广告
  12. c.desc();
  13. //客户不满意 奔驰 4S店的 服务态度,又进了一家4S店,一看是别克的4S店
  14. _4S = new Buick4S();
  15. //然后选择了 跑车
  16. c = _4S.choiceBusiness();
  17. //然后看了下这个车的简介
  18. c.desc();
  19. }
  20. }
运行结果如下:


总结:
抽象工厂模式,是对产品族进行了抽象。这里引入了一个新概念,产品族。
通过百度百科查询,解释的太抽象了,不是那么容易理解,可以自行对其下定义:
首先是很多的产品组合在一起的一个族群,不用的族群之间的每个产品都有相同的属性,但是由于另外的分族规则被隔离开来,他侧重的是族群之间的产品即存在相似的地方,又可以被区分开来,它所注重的是族群间的关系,而非一个族之内的关系。
针对这个例子而言,跑车、商用车可以产生很多产品,比如奔驰和别克,但是品牌这个规则,将这些产品形成了两个产品族--一个奔驰产品族,一个别克产品族。但是两个产品族中的的确存在一一对应的产品(奔驰跑车、别克跑车),还可以再举一个例子,李宁专卖店,安踏专卖店,361专卖店,特步专卖店,这几个就是几个产品族,每个产品族中的产品都可以在另外一个产品族中找到类似的产品,比如都卖鞋,裤子,上衣等。
甚至,还有一个例子,乒乓球运动品专卖店,羽毛球运动品专卖店(假设两家只卖球拍和球),那么这两个族就很明显了,球拍都可以抽象到一个类,球也可以抽象到一个类。那这个就是两个产品族。

区别与工厂方法模式,工厂方法模式对的抽象,只是对产品工厂的抽象,而抽象工厂则是对产品族工厂的抽象。所以,有一种说法:工厂方法模式是抽象工厂模式的一个特例(产品族中只有一个产品),即抽象工厂模式是工厂方法模式的一般化。

答疑:
针对在产品进行抽象的过程中,是这么抽象的:
Car -- SportCar、BusinessCar -- BenzSportCar、BuickSportCar……
首先派生 车的类型,然后才派生出车的品牌。
以车来看,其类型比其品牌更加接近属性。毕竟,如果车型相同类,随你怎么贴商标。


此模式的优缺点:
优点:其实就是使用了产品族的优点,对产品进行了区分隔离,保证了产品类的范围,在一定程度上实现了封装。
缺点:一旦产品族中有新的产品,那么,所有产品族工厂类,对产品族工厂抽象类,都要调整,没有发现,这个进行的维护成本远远的增加了







转载于:https://my.oschina.net/u/1182369/blog/406570

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值