不知道为什么就是很喜欢汉堡,不知道吃什么的时候基本上都会选择吃汉堡,我绝对是肯德基、麦当劳、汉堡王的常客。如果把买汉堡这个行为放在代码的世界里,那绝对是抽象工厂模式没跑了。
比如我说我要去汉堡店,那么好,汉堡店就是抽象工厂;然后我要在不同的汉堡店里选择一家去消费,那么,多家不同的汉堡店就是抽象工厂的具体工厂;当我确定要在哪一家消费后,我就要开始选择要购入的产品;然后产品种类繁多,有汉堡、有薯条,汉堡又包含牛肉堡、鸡腿堡,薯条也可分为大份和中份。没办法,我只好将产品大类也抽象出来,然后在基于产品抽象类派生出多个具体的产品,至此一个可以制作汉堡的工厂就完成了,如下图所示。
我自认为这个图画的还是非常的形象,紧接着用代码来实现一下吧~
既然我想吃汉堡,那我肯定要去汉堡店,因为此时我还不知道要去哪一个汉堡店,所以我只能先创建一个抽象的汉堡店
java
代码解读
复制代码
/** * 汉堡店抽象类 */ public abstract class HamburgFactory { /** * 获取汉堡的抽象方法 * @return */ public abstract Burger getBurger(); }
因为现在有三家汉堡店,所以我要再创建三个具体的工厂类
java
代码解读
复制代码
//肯德基工厂 public class KFCHamburgFactory extends HamburgFactory{ @Override public Burger getBurger() { return new KFCBurger(); } }
java
代码解读
复制代码
//汉堡王工厂 public class KingHamburgFactory extends HamburgFactory { @Override public Burger getBurger() { return new KingBurger(); } }
java
代码解读
复制代码
//麦当劳工厂 public class MDLHamburgFactory extends HamburgFactory { @Override public Burger getBurger() { return new MDLBurger(); } }
抽象工厂类和工厂类中都包含一个获取汉堡产品的方法,用来获取具体的汉堡产品类,所以也要有一个产品抽象类
这边整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题
需要全套面试笔记的【点击此处即可】免费获取
java
代码解读
复制代码
//抽象产品汉堡 public interface Burger { //鸡腿堡 void chickenBurger(); //牛肉堡 void beefBurger(); //辣堡 void SpicyBurger(); //田园堡 void tianyuanBurger(); }
因为有三家汉堡店可以选择,并且三家汉堡店所能加工的汉堡是不一样的,所以需要三个具体的产品类来制作不同的汉堡
java
代码解读
复制代码
//肯德基汉堡具体产品 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-没有辣堡"); } }
java
代码解读
复制代码
//汉堡王具体汉堡产品 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-没有田园堡"); } }
java
代码解读
复制代码
//麦当劳具体汉堡产品 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-没有田园堡"); } }
三家不同的汉堡店包含的产品是不同的,想要吃什么汉堡就要去特定的门店才行,需要去哪家门店就要去实例化哪个门店的汉堡工厂,再通过具体的汉堡示例得到想要的汉堡。
编写测试类演示工厂模式的使用
java
代码解读
复制代码
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()
之后,就得到了一份肯德基鸡腿堡!
上面的测试代码执行的结果如下图所示:
总结
抽象工厂模式的好处是让程序在一定程度上解耦,将不同的产品区分开,比如肯德基只生产肯德基的汉堡,麦当劳只生产麦当劳的汉堡,互相之间不干扰。并且隐藏了各个产品的实现细节,简化了后期生产产品的更新工作。
抽象工厂模式的缺点是代码过于抽象,增加了系统得理解难度。