简介
工厂模式有三兄弟,第一是简单工厂,这个勉强算是一种设计模式,第二个是工厂模式,我也写过了,今天就介绍不太好理解的第三种模式:抽象工厂模式。
情景
在商场里面有买冰淇凌的机器,每一种口味都是一台机器,比如苹果冰淇凌机器,比如香蕉冰淇凌机器,同时呢,每一个机器都可以选择中国产的和美国产的,当然价格不一样。现在就是抽象工厂模式应用适合的场景了。
实体类
既然是冰淇凌机器,我们首先就要有冰淇凌。
无论是美国的,还是中国的,都是冰淇凌,所以我把冰淇凌类抽象了。
public abstract class IceCream{
private String production;
public IceCream(){
this.production=setProducton();
}
//设置产地:美国还是中国
abstract String setProducton();
//口味,每种冰淇凌都不一样
abstract String taste();
@Override
public String toString() {
return "IceCream [production=" + production + "]";
}
接下来我又有两个实现了冰淇凌类
中国的:
public abstract class ChinaIcream extends IceCream {
@Override
String setProducton() {
return "china";
}
美国的:
public abstract class AmericanIceram extends IceCream{
@Override
String setProducton() {
return "American";
}
}
好了,接下来我们到了具体的
public class ChinaAppleIceam extends ChinaIcream {
@Override
String taste() {
return " apple icream is like a apple";
}
@Override
public String toString() {
return "ChinaAppleIceam [taste()=" + taste() + ", toString()="
+ super.toString() + "]";
}
}
美国的:
public class AmericanAppleIcream extends AmericanIceram {
@Override
String taste() {
return "American apple iceram is less and expensive";
}
@Override
public String toString() {
return "AmericanAppleIcream [taste()=" + taste() + ", toString()="
+ super.toString() + "]";
}
}
接下来,暂停一下
如果是不用工厂模式,我们会怎么做?
public class WrongMachine {
private String kind;// 品种:苹果还是香蕉等
private String Style;// china America
public WrongMachine(String kind, String Style) {
this.kind = kind;
this.Style = Style;
}
IceCream cell() {
if (kind.equals("apple")) {
if (Style.equals("china")) {
return new ChinaAppleIceam();
} else {
return new AmericanAppleIcream();
}
} else {
return null;
}
}
}
细细看,有什么问题,假如我新假如其他的品种呢?
现在只有两种冰淇凌,如果我加入很多的其他的品种,那么我每一次加入新的冰淇凌都会要修改cell 方法。
这样是违反开闭原则的
那么加入工厂方法试试
public interface Icreamfactory {
ChinaIcream createChinaIcream();//生产中国的冰淇凌
AmericanIceram createAmericanIceram();//美国的
}
注意,我们在抽象工厂方法里面返回的两种生产方法也是抽象的,这样才能扩展。
下面开始写苹果冰淇凌制造厂
public class AppleFactory implements Icreamfactory{
@Override
public ChinaIcream createChinaIcream() {
return new ChinaAppleIceam();
}
@Override
public AmericanIceram createAmericanIceram() {
return new AmericanAppleIcream();
}
}
下面是贩卖机的代码
public class IceramSellMachine {
private Icreamfactory icreamfactory;
//我们在一开始传入一个抽象的工厂,不依赖于具体的工厂创建实体类。
public IceramSellMachine(Icreamfactory icreamfactory){
this.icreamfactory=icreamfactory;
}
ChinaIcream produceChina(){
return icreamfactory.createChinaIcream();
}
AmericanIceram produceAmerica(){
return icreamfactory.createAmericanIceram();
}
IceCream cell(String Style){
if("china".equals(Style)){
return produceChina();
}else{
return produceAmerica();
}
}
}
public class TestStore {
public static void main(String[] args) {
System.out.println("顾客走向了苹果冰淇凌机器:");
System.out.println("请输入您想要的品种?");
Icreamfactory icreamfactory=new AppleFactory();
IceramSellMachine store =new IceramSellMachine(icreamfactory);
@SuppressWarnings("resource")
Scanner scanner=new Scanner(System.in);
String style=scanner.next();
IceCream I= store.cell(style);
System.out.println(I.toString());
}
}
让我们测试一下好了:
顾客走向了苹果冰淇凌机器:
请输入您想要的品种?
:china
ChinaAppleIceam [taste()= apple icream is like a apple, toString()=IceCream [production=china]]
那么现在我们不单单卖苹果味道的冰淇凌了,我们开始卖香蕉味道的。
当然新建实体类:
public class ChinaBananaIcream extends ChinaIcream {
@Override
String taste() {
return "banana icream is like a banana";
}
@Override
public String toString() {
return "ChinaBananaIcream [taste()=" + taste() + ", toString()="
+ super.toString() + "]";
}
}
美国的
public class AmericanBananaIcream extends AmericanIceram{
@Override
String taste() {
return "American banana icream is import form NewYork";
}
@Override
public String toString() {
return "AmericanBananaIcream [taste()=" + taste() + ", toString()="
+ super.toString() + "]";
}
}
共产
public class BananaFactory implements Icreamfactory{
@Override
public ChinaIcream createChinaIcream() {
return new ChinaBananaIcream();
}
@Override
public AmericanIceram createAmericanIceram() {
return new AmericanBananaIcream();
}
}
测试
public class TestStore {
public static void main(String[] args) {
System.out.println("顾客走向了香蕉冰淇凌机器:");
System.out.println("请输入您想要的品种?");
Icreamfactory icreamfactory=new BananaFactory();
IceramSellMachine store =new IceramSellMachine(icreamfactory);
@SuppressWarnings("resource")
Scanner scanner=new Scanner(System.in);
String style=scanner.next();
IceCream I= store.cell(style);
System.out.println(I.toString());
}
}
结果
顾客走向了香蕉冰淇凌机器:
请输入您想要的品种?
china
ChinaBananaIcream [taste()=banana icream is like a banana, toString()=IceCream [production=china]]
看到了吗?
我们的贩卖机代码一点也没有改变!
总结
这就是抽象工厂模式。
抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,它是一种对象创建型模式。
在抽象工厂模式中,每一个具体工厂都提供了多个工厂方法用于产生多种不同类型的产品,这些产品构成了一个产品族。