先吐槽下,学习工厂模式时候,开始的时候都很恶心,但是反复的研究,明白后,并写出来后,才发现,真的值。
现在开始正式进入抽象工厂模式的学习和了解。
结合 工厂方法模式中所举的例子,为了更好的理解抽象工厂模式,我们把例子稍微调整下,不再以中国人外国人不能举例子,不是说不能用这个中国人外国人的例子,而是我发现有更好的例子。
我们换做汽车的例子来举例,首先 定义抽象类Car,然后用派生出子抽象类 ,SportCar,BusinessCar,分别是
跑车和商务车,派生出来的子类还是抽象类,因为还有如下:SportBenzCar(
奔驰跑车),BusinessBenzCar(
奔驰商用
),SportBuickCar,BusinessBuickCar(此处需要想想,为什么抽象类Car的直接子类是SportCar和BusnessCar,然后这两个类的子类才是Benz和Buick,而不是Car的直接子类是BenzCar和BuickCar),所以来吧,先把几个抽象类和具体实现类给搞定,
具体的类如下:
代码实现如下:(几个文件的内容全都放在一起了)
//定义车抽象产品,用途只体现在多态,客户端用此定义产品对象,子类或者子类工厂类实例化
public abstract class Car {
public abstract void desc();
}
//Car派生的子类,还是抽象产品,包含跑车和商务车
public abstract class SportCar extends Car {}
public abstract class BusinessCar extends Car {}
//接下来不同品牌对两种车型的实现
public class SportBenzCar extends SportCar {
public void desc() {
System.out.println("哥就是传说中的奔驰跑车!");
}
}
public class BusinessBenzCar extends BusinessCar {
public void desc() {
System.out.println("奔驰商务车,成功人士的选择");
}
}
public class SportBuickCar extends SportCar {
public void desc() {
System.out.println("本少即别克跑车!");
}
}
public class BusinessBuickCar extends BusinessCar {
public void desc() {
System.out.println("商用别克,让您快乐");
}
}
以上是对产品的抽象类和具体类的编写,之后,我们模拟下,客户买车的环节的步骤:
1、进入一家4S店(或者是随便进一家,或者是指定的进入一家)
2、选择车类型(要么是自己心里有喜欢的车型了,或者是听4S店销售介绍)
那么问题来了,这个4S店怎么在我们的程序中体现?4S店开始有很多的,有宝马4S,福特4S,奔驰4S,别克4S等等,但是相同的是,每家4S店都是可以出售各种类型的,这样以来,我们还需要对4S店进行抽象,如下:
//抽象4S店
public abstract class SaleCar4S {
public abstract SportCar choiceSport();
public abstract BusinessCar choiceBusiness();
//只是举了两个例子,可能还会包含 房车,越野车,甲壳虫等等车型
}
//奔驰4S店
public class Benz4S extends SaleCar4S {
public SportCar choiceSport() {
return new SportBenzCar();
}
public BusinessCar choiceBusiness() {
return new BusinessBenzCar();
}
}
//别克4S店
public class Buick4S extends SaleCar4S {
public SportCar choiceSport() {
return new SportBuickCar();
}
public BusinessCar choiceBusiness() {
return new BusinessBuickCar();
}
}
好了,现在可以写客户端代码了,客户端代码是按照我们刚刚的买车步骤来的:
public class Start {
public static void main(String[] args) {
//购车客户走进了一家卖车的4S店,一看是奔驰的4S店
SaleCar4S _4S = new Benz4S();
//然后 从这个4S店里面找了一款商用车
Car c = _4S.choiceBusiness();
//这款商务车的广告
c.desc();
//客户嫌广告词太老,不喜欢,于是重新选择了一辆跑车
c = _4S.choiceSport();
//这款跑车的广告
c.desc();
//客户不满意 奔驰 4S店的 服务态度,又进了一家4S店,一看是别克的4S店
_4S = new Buick4S();
//然后选择了 跑车
c = _4S.choiceBusiness();
//然后看了下这个车的简介
c.desc();
}
}
运行结果如下:
总结:
抽象工厂模式,是对产品族进行了抽象。这里引入了一个新概念,产品族。
通过百度百科查询,解释的太抽象了,不是那么容易理解,可以自行对其下定义:
首先是很多的产品组合在一起的一个族群,不用的族群之间的每个产品都有相同的属性,但是由于另外的分族规则被隔离开来,他侧重的是族群之间的产品即存在相似的地方,又可以被区分开来,它所注重的是族群间的关系,而非一个族之内的关系。
针对这个例子而言,跑车、商用车可以产生很多产品,比如奔驰和别克,但是品牌这个规则,将这些产品形成了两个产品族--一个奔驰产品族,一个别克产品族。但是两个产品族中的的确存在一一对应的产品(奔驰跑车、别克跑车),还可以再举一个例子,李宁专卖店,安踏专卖店,361专卖店,特步专卖店,这几个就是几个产品族,每个产品族中的产品都可以在另外一个产品族中找到类似的产品,比如都卖鞋,裤子,上衣等。
甚至,还有一个例子,乒乓球运动品专卖店,羽毛球运动品专卖店(假设两家只卖球拍和球),那么这两个族就很明显了,球拍都可以抽象到一个类,球也可以抽象到一个类。那这个就是两个产品族。
区别与工厂方法模式,工厂方法模式对的抽象,只是对产品工厂的抽象,而抽象工厂则是对产品族工厂的抽象。所以,有一种说法:工厂方法模式是抽象工厂模式的一个特例(产品族中只有一个产品),即抽象工厂模式是工厂方法模式的一般化。
答疑:
针对在产品进行抽象的过程中,是这么抽象的:
Car -- SportCar、BusinessCar -- BenzSportCar、BuickSportCar……
首先派生 车的类型,然后才派生出车的品牌。
以车来看,其类型比其品牌更加接近属性。毕竟,如果车型相同类,随你怎么贴商标。
此模式的优缺点:
优点:其实就是使用了产品族的优点,对产品进行了区分隔离,保证了产品类的范围,在一定程度上实现了封装。
缺点:一旦产品族中有新的产品,那么,所有产品族工厂类,对产品族工厂抽象类,都要调整,没有发现,这个进行的维护成本远远的增加了
转载于:https://my.oschina.net/u/1182369/blog/406570