抽象工厂模式——肯德基消费
一 模式定义
- 抽象工厂模式提供了一个接口,用于创建相关或者依赖对象的家族,而不需要指定具体实现类。
- 抽象工厂模式允许客户使用抽象接口来创建一组相关的产品,客户类和工厂类分开,客户需要任何产品的时候,只需要向工厂请求即可,客户无须修改就可以获得新产品。
二 模式举例
1 模式分析
我们借用爸爸和儿子到肯德基店消费这一场景来说明这一模式,进行抽象分析后的截图如下
2 抽象工厂模式的静态建模
3 代码示例
3.1 抽象食物的建立
抽象食物——AbstractBaseFood
package com.demo.factory.model; /** * * 食物基类 * * @author maofw * */ public abstract class AbstractBaseFood { // 类别 protected String kind; // 数量 protected int num; // 价格 protected float price; // 合计 public float totalPrice() { return this.num * this.price; } }
食物接口——IFood
package com.demo.factory.model; /** * 抽象食物接口 * * @author maofw * */ public interface IFood { /** * 打印输出食物信息 */ void printMesage(); }
3.2 建立不同食物的抽象基类
汉堡基类——Hamburg
package com.demo.factory.model; /** * 汉堡基类 * * @author maofw * */ public abstract class Hamburg extends AbstractBaseFood implements IFood { public void printMesage() { System.out.println("--" + this.kind + "风味汉堡,\t单价:" + this.price + ",\t数量:" + this.num + ",\t合计:" + this.totalPrice()); } }
鸡翅基类——ChickenWings
package com.demo.factory.model; /** * 鸡翅基类 * * @author maofw * */ public abstract class ChickenWings extends AbstractBaseFood implements IFood { public void printMesage() { System.out.println("--" + this.kind + "风味鸡翅,\t单价:" + this.price + ",\t数量:" + this.num + ",\t合计:" + this.totalPrice()); } }
薯条基类——FrenchFries
package com.demo.factory.model; /** * 薯条基类 * * @author maofw * */ public abstract class FrenchFries extends AbstractBaseFood implements IFood { public void printMesage() { System.out.println("--" + this.kind + "风味薯条,\t单价:" + this.price + ",\t数量:" + this.num + ",\t合计:" + this.totalPrice()); } }
饮料基类——Beverage
package com.demo.factory.model; /** * 饮料基类 * * @author maofw * */ public abstract class Beverage extends AbstractBaseFood implements IFood { public void printMesage() { System.out.println("--" + this.kind + "饮料,\t单价:" + this.price + ",\t数量:" + this.num + ",\t合计:" + this.totalPrice()); } }
3.3 创建具体的食物
麻辣鸡腿汉堡——ChinaHanburm
package com.demo.factory.model.kfc; import com.demo.factory.model.Hamburg; /** * 中国风味的麻辣鸡腿汉堡 * * @author maofw * */ public class ChinaHanburm extends Hamburg { /** * 构造方法 * * @param kind * @param price * @param num */ public ChinaHanburm(int num) { this.kind = "麻辣"; this.price = 14.0f; this.num = num; } }
奥尔良鸡翅——ChinaChickenWings
package com.demo.factory.model.kfc; import com.demo.factory.model.ChickenWings; /** * 鸡翅实现类 * * @author maofw * */ public class ChinaChickenWings extends ChickenWings { public ChinaChickenWings(int num) { this.kind = "奥尔良"; this.price = 2.5f; this.num = num; } }
薯条——ChinaFrenchFries
package com.demo.factory.model.kfc; import com.demo.factory.model.FrenchFries; /** * 薯条实现类 * * @author maofw * */ public class ChinaFrenchFries extends FrenchFries { public ChinaFrenchFries(int num) { this.kind = "普通"; this.price = 8.0f; this.num = num; } }
可乐——ChinaBeverage
package com.demo.factory.model.kfc; import com.demo.factory.model.Beverage; /** * 饮料实现类 * * @author maofw * */ public class ChinaBeverage extends Beverage { public ChinaBeverage(int num) { this.kind = "可乐"; this.price = 7.0f; this.num = num; } }
3.4 建立工厂
创建抽象肯德基工厂——IKfcFactory 生产抽象食物
package com.demo.factory.itf; import com.demo.factory.model.Beverage; import com.demo.factory.model.ChickenWings; import com.demo.factory.model.FrenchFries; import com.demo.factory.model.Hamburg; /** * 肯德基抽象工厂基类 * * @author maofw * */ public interface IKfcFactory { // 生产汉堡 public Hamburg createHamburg(int num); // 生产薯条 public FrenchFries createFrenchFries(int num); // 生产鸡翅 public ChickenWings createChickenWings(int num); // 生产饮料 public Beverage createBeverage(int num); }
创建具体肯德基工厂——ChinaKfcFactory 生产具体食物
package com.demo.factory.itf; import com.demo.factory.model.Beverage; import com.demo.factory.model.ChickenWings; import com.demo.factory.model.FrenchFries; import com.demo.factory.model.Hamburg; import com.demo.factory.model.kfc.ChinaBeverage; import com.demo.factory.model.kfc.ChinaChickenWings; import com.demo.factory.model.kfc.ChinaFrenchFries; import com.demo.factory.model.kfc.ChinaHanburm; public class ChinaKfcFactory implements IKfcFactory { // 生产可乐 public Beverage createBeverage(int num) { return new ChinaBeverage(num); } // 生产奥尔良烤鸡翅 public ChickenWings createChickenWings(int num) { return new ChinaChickenWings(num); } // 生产薯条 public FrenchFries createFrenchFries(int num) { return new ChinaFrenchFries(num); } // 生产麻辣风味鸡腿汉堡 public Hamburg createHamburg(int num) { return new ChinaHanburm(num); } }
3.5 创建客户类——Customer
package com.demo.factory.custom; import com.demo.factory.itf.IKfcFactory; import com.demo.factory.model.Beverage; import com.demo.factory.model.ChickenWings; import com.demo.factory.model.FrenchFries; import com.demo.factory.model.Hamburg; /** * 客户类 * * @author maofw * */ public class Customer { // 抽象工厂 private IKfcFactory kfcFactory; // 构造方法将抽象工厂作为参数传入 public Customer(IKfcFactory kfcFactory) { this.kfcFactory = kfcFactory; } /** * 订购食物 */ // 订购麻辣鸡腿汉堡 public float orderHamburg(int num) { // 获得麻辣鸡腿汉堡 Hamburg hamburg = kfcFactory.createHamburg(num); // 输出订购信息 hamburg.printMesage(); // 返回总价 return hamburg.totalPrice(); } // 订购奥尔良烤鸡翅 public float orderChickenWings(int num) { // 获得奥尔良烤鸡翅 ChickenWings chickenWings = kfcFactory.createChickenWings(num); // 输出订购信息 chickenWings.printMesage(); // 返回总价 return chickenWings.totalPrice(); } // 订购薯条 public float orderFrenchFries(int num) { // 获得薯条 FrenchFries frenchFries = kfcFactory.createFrenchFries(num); // 输出订购信息 frenchFries.printMesage(); // 返回总价 return frenchFries.totalPrice(); } // 订购可乐 public float orderBeverage(int num) { // 获得可乐 Beverage beverage = kfcFactory.createBeverage(num); // 输出订购信息 beverage.printMesage(); // 返回总价 return beverage.totalPrice(); } }
3.6 故事情节展现
package com.demo.factory; import java.lang.management.ManagementFactory; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.text.NumberFormat; import java.util.Arrays; import java.util.Calendar; import java.util.ResourceBundle; import com.demo.factory.custom.Customer; import com.demo.factory.itf.ChinaKfcFactory; import com.demo.factory.itf.IKfcFactory; public class MainApp { /** * 主应用程序方法 * * @param args */ public static void main(String[] args) { /** * 定义一个肯德基(IKfcFactory类型) */ IKfcFactory kfcFactory = new ChinaKfcFactory(); /** * 爸爸和儿子走进肯德基,准备点餐 */ Customer customer = new Customer(kfcFactory); /** * 开始点餐 */ // 一个麻辣鸡腿汉堡 float hamhurgMoney = customer.orderHamburg(1); // 四个奥尔良烤鸡翅 float chickenWingsMoney = customer.orderChickenWings(4); // 一包薯条 float frenchFriesMoney = customer.orderFrenchFries(1); // 两杯可乐 float beverageMoney = customer.orderBeverage(2); System.out.println("总计:" + (hamhurgMoney + chickenWingsMoney + frenchFriesMoney + beverageMoney)); } }
运行结果:
--麻辣风味汉堡, 单价:14.0, 数量:1, 合计:14.0
--奥尔良风味鸡翅, 单价:2.5, 数量:4, 合计:10.0
--普通风味薯条, 单价:8.0, 数量:1, 合计:8.0
--可乐饮料, 单价:7.0, 数量:2, 合计:14.0
总计:46.0
三 该模式的设计原则
1 多用对象组合,少用继承
2 针对抽象编程,不针对实现编程
3 产品对象通过工厂暴露的方法创建
四 使用场合
1 创建产品家族,相关产品集合在一起使用的时候;
2 想要提供一个产品类库,并只想显示其接口而不是实现时;
3 通过组合的方式使用工厂时。