不知道为什么就是很喜欢汉堡,不知道吃什么的时候基本上都会选择吃汉堡,我绝对是肯德基、麦当劳、汉堡王的常客。如果把买汉堡这个行为放在代码的世界里,那绝对是抽象工厂模式没跑了。
比如我说我要去汉堡店,那么好,汉堡店就是抽象工厂;然后我要在不同的汉堡店里选择一家去消费,那么,多家不同的汉堡店就是抽象工厂的具体工厂;当我确定要在哪一家消费后,我就要开始选择要购入的产品;然后产品种类繁多,有汉堡、有薯条,汉堡又包含牛肉堡、鸡腿堡,薯条也可分为大份和中份。没办法,我只好将产品大类也抽象出来,然后在基于产品抽象类派生出多个具体的产品,至此一个可以制作汉堡的工厂就完成了,如下图所示。
我自认为这个图画的还是非常的形象,紧接着用代码来实现一下吧~
既然我想吃汉堡,那我肯定要去汉堡店,因为此时我还不知道要去哪一个汉堡店,所以我只能先创建一个抽象的汉堡店
/**
* 汉堡店抽象类
*/
public abstract class HamburgFactory {
/**
* 获取汉堡的抽象方法
* @return
*/
public abstract Burger getBurger();
}
因为现在有三家汉堡店,所以我要再创建三个具体的工厂类
//肯德基工厂
public class KFCHamburgFactory extends HamburgFactory{
@Override
public Burger getBurger() {
return new KFCBurger();
}
}
//汉堡王工厂
public class KingHamburgFactory extends HamburgFactory {
@Override
public Burger getBurger() {
return new KingBurger();
}
}
//麦当劳工厂
public class MDLHamburgFactory extends HamburgFactory {
@Override
public Burger getBurger() {
return new MDLBurger();
}
}
抽象工厂类和工厂类中都包含一个获取汉堡产品的方法,用来获取具体的汉堡产品类,所以也要有一个产品抽象类
//抽象产品汉堡
public interface Burger {
//鸡腿堡
void chickenBurger();
//牛肉堡
void beefBurger();
//辣堡
void SpicyBurger();
//田园堡
void tianyuanBurger();
}
因为有三家汉堡店可以选择,并且三家汉堡店所能加工的汉堡是不一样的,所以需要三个具体的产品类来制作不同的汉堡
//肯德基汉堡具体产品
public class KFCBurger implements Burger{
//鸡腿堡
public void chickenBurger() {
System.out.println("KFC-鸡腿堡,请取餐");
}
//田园堡
public void tianyuanBurger() {
System.out.println("KFC-田园堡,请取餐");
}
@Override
public void beefBurger() {
System.out.println("KFC-没有牛肉堡");
}
@Override
public void SpicyBurger() {
System.out.println("KFC-没有辣堡");
}
}
//汉堡王具体汉堡产品
public class KingBurger implements Burger{
//鸡腿堡
public void chickenBurger() {
System.out.println("King-鸡腿堡,请取餐");
}
//牛肉堡
public void beefBurger() {
System.out.println("King-牛肉堡,请取餐");
}
@Override
public void SpicyBurger() {
System.out.println("King-没有辣堡");
}
@Override
public void tianyuanBurger() {
System.out.println("King-没有田园堡");
}
}
//麦当劳具体汉堡产品
public class MDLBurger implements Burger{
//鸡腿堡
public void chickenBurger() {
System.out.println("MDL-鸡腿堡,请取餐");
}
//辣堡
public void SpicyBurger() {
System.out.println("MDL-辣堡,请取餐");
}
@Override
public void beefBurger() {
System.out.println("MDL-没有牛肉堡");
}
@Override
public void tianyuanBurger() {
System.out.println("MDL-没有田园堡");
}
}
三家不同的汉堡店包含的产品是不同的,想要吃什么汉堡就要去特定的门店才行,需要去哪家门店就要去实例化哪个门店的汉堡工厂,再通过具体的汉堡示例得到想要的汉堡。
编写测试类演示工厂模式的使用
public class test_01 {
public static void main(String[] args) {
//点个肯德基
HamburgFactory KFCfactory = new KFCHamburgFactory();
Burger KFC = KFCfactory.getBurger();
KFC.chickenBurger();
//点个麦当劳
HamburgFactory MDLfactory = new MDLHamburgFactory();
Burger MDL = MDLfactory.getBurger();
MDL.chickenBurger();
MDL.tianyuanBurger();
//点个汉堡王
HamburgFactory Kingfactory = new KingHamburgFactory();
Burger King = Kingfactory.getBurger();
King.chickenBurger();
King.beefBurger();
}
}
上面的代码示例中,如果想要吃肯德基,那么就要先拿到具体的工厂KFCHamburgFactory,在工厂实例中,我们可以调用getBurger()得到这个工厂中所能生产的汉堡产品,也就是KFCBurger实例,拿到这个实例后就可以调用具体的方法制作我们想要的汉堡,比如上面的代码执行KFC.chickenBurger()之后,就得到了一份肯德基鸡腿堡!
上面的测试代码执行的结果如下图所示:
总结
抽象工厂模式的好处是让程序在一定程度上解耦,将不同的产品区分开,比如肯德基只生产肯德基的汉堡,麦当劳只生产麦当劳的汉堡,互相之间不干扰。并且隐藏了各个产品的实现细节,简化了后期生产产品的更新工作。
抽象工厂模式的缺点是代码过于抽象,增加了系统得理解难度。