在Java中使用抽象工厂模式实现买汉堡

195 阅读4分钟

不知道为什么就是很喜欢汉堡,不知道吃什么的时候基本上都会选择吃汉堡,我绝对是肯德基、麦当劳、汉堡王的常客。如果把买汉堡这个行为放在代码的世界里,那绝对是抽象工厂模式没跑了。

比如我说我要去汉堡店,那么好,汉堡店就是抽象工厂;然后我要在不同的汉堡店里选择一家去消费,那么,多家不同的汉堡店就是抽象工厂的具体工厂;当我确定要在哪一家消费后,我就要开始选择要购入的产品;然后产品种类繁多,有汉堡、有薯条,汉堡又包含牛肉堡、鸡腿堡,薯条也可分为大份和中份。没办法,我只好将产品大类也抽象出来,然后在基于产品抽象类派生出多个具体的产品,至此一个可以制作汉堡的工厂就完成了,如下图所示。

hbg.png

我自认为这个图画的还是非常的形象,紧接着用代码来实现一下吧~

既然我想吃汉堡,那我肯定要去汉堡店,因为此时我还不知道要去哪一个汉堡店,所以我只能先创建一个抽象的汉堡店

/**
 * 汉堡店抽象类
 */
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()之后,就得到了一份肯德基鸡腿堡!

上面的测试代码执行的结果如下图所示:

image.png

总结

抽象工厂模式的好处是让程序在一定程度上解耦,将不同的产品区分开,比如肯德基只生产肯德基的汉堡,麦当劳只生产麦当劳的汉堡,互相之间不干扰。并且隐藏了各个产品的实现细节,简化了后期生产产品的更新工作。

抽象工厂模式的缺点是代码过于抽象,增加了系统得理解难度。