通俗理解工厂模式,工厂模式三种详解

首页 > 科技 > 作者:YD1662024-07-04 04:55:24

核心作用

定义一个用于创建产品的接口,由子类决定生产什么产品。

分类
  1. 简单工厂模式
  2. 工厂方法模式
  3. 抽象工厂模式
简单工厂模式

简单工厂模式是有一个工厂对象决定创建出哪一种产品类的实例。即定义了一个创建对象的类,由这个类来封装实例化对象的行为。

简单工厂有两种模式:

  1. 普通简单工厂模式;
  2. 静态简单工厂模式;
简单工厂模式的主要角色优势劣势

● 简单工厂模式,通过接收的参数不同来返回不同的对象实例;
● 对于增加新产品(新功能)无能为力!不修改代码的话,是无法扩展的。不满足开闭原则。

简单工厂模式的实现

抽象类Pizza

package top.simba1949.factory.simple.pizza; import lombok.Data; import lombok.extern.slf4j.Slf4j; /** * @author anthony * @datetime 2020/5/9 11:45 */ @Slf4j @Data public abstract class Pizza { protected String name; /** * 准备原材料,每种 Pizza 原材料不一致 */ public abstract void prepare(); /** * Pizza 烘烤 */ public void bake() { log.info("{} : baking", name); } /** * Pizza 切割 */ public void cut() { log.info("{} : cutting", name); } /** * Pizza 打包 */ public void box() { log.info("{} : boxing", name); } }

抽象类Pizza的实现

package top.simba1949.factory.simple.pizza; import lombok.extern.slf4j.Slf4j; /** * @author anthony * @datetime 2020/5/9 11:51 */ @Slf4j public class CheesePizza extends Pizza { @Override public void prepare() { log.info("芝士Pizza原材料准备中。。。"); } }

package top.simba1949.factory.simple.pizza; import lombok.extern.slf4j.Slf4j; /** * @author anthony * @datetime 2020/5/9 11:52 */ @Slf4j public class GreekPizza extends Pizza { @Override public void prepare() { log.info("希腊风味Pizza原材料准备中。。。"); } }

简单工厂(静态)

package top.simba1949.factory.simple.staticFacotry; import top.simba1949.factory.simple.pizza.CheesePizza; import top.simba1949.factory.simple.pizza.GreekPizza; import top.simba1949.factory.simple.pizza.Pizza; /** * @author anthony * @datetime 2020/5/9 12:51 */ public class SimpleFactoryByStatic { public static Pizza orderPizza(String type) { Pizza pizza = null; if ("cheese".equalsIgnoreCase(type)) { pizza = new CheesePizza(); pizza.setName("cheese"); } else if ("greek".equalsIgnoreCase(type)) { pizza = new GreekPizza(); pizza.setName("greek"); } if (null != pizza){ pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } return pizza; } }

简单工厂模式(普通)

package top.simba1949.factory.simple.commonFactory; import top.simba1949.factory.simple.pizza.CheesePizza; import top.simba1949.factory.simple.pizza.GreekPizza; import top.simba1949.factory.simple.pizza.Pizza; /** * @author anthony * @datetime 2023/7/15 13:19 */ public class SimpleFactoryByCommon { public Pizza orderPizza(String type) { Pizza pizza = null; if ("cheese".equalsIgnoreCase(type)) { pizza = new CheesePizza(); pizza.setName("cheese"); } else if ("greek".equalsIgnoreCase(type)) { pizza = new GreekPizza(); pizza.setName("greek"); } if (null != pizza){ pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } return pizza; } }

测试类

package top.simba1949.factory.simple; import lombok.extern.slf4j.Slf4j; import top.simba1949.factory.simple.commonFactory.SimpleFactoryByCommon; import top.simba1949.factory.simple.pizza.Pizza; import top.simba1949.factory.simple.staticFacotry.SimpleFactoryByStatic; /** * @author anthony * @datetime 2020/5/9 13:50 */ @Slf4j public class SimpleFactoryApplication { public static void main(String[] args) { String pizzaType = "cheese"; // 简单工厂(静态)模式 // simpleFactoryByStatic(pizzaType); // 简单工厂(普通)模式 simpleFactoryByCommon(pizzaType); } public static void simpleFactoryByStatic(String pizzaType){ // 用户订购 Pizza Pizza pizza = SimpleFactoryByStatic.orderPizza(pizzaType); // 得到 Pizza log.info("简单工厂(静态):订购的披萨是{}", pizza); } public static void simpleFactoryByCommon(String pizzaType){ SimpleFactoryByCommon simpleFactoryByCommon = new SimpleFactoryByCommon(); // 用户订购 Pizza Pizza pizza = simpleFactoryByCommon.orderPizza(pizzaType); // 得到 Pizza log.info("简单工厂(普通):订购的披萨是{}", pizza); } }工厂方法模式

工厂方法模式:定义了一个创建对象的抽象方法,由子类决定要实例化的类。
工程方法模式将对象的实例化推迟到子类实例化。

工厂方法模式的主要角色工厂方法模式优缺点

优点

缺点

工厂方法模式的实现

UML 类图描述

通俗理解工厂模式,工厂模式三种详解(1)


咖啡类

package top.simba1949.factory.method.coffee; import lombok.Data; import lombok.extern.slf4j.Slf4j; /** * @author anthony * @datetime 2023/7/15 13:46 */ @Slf4j @Data public abstract class Coffee { private String name; public void addMilk(){ log.info("{} 添加了牛奶", name); } public void addSugar(){ log.info("{} 添加了糖", name); } }

package top.simba1949.factory.method.coffee; /** * @author anthony * @datetime 2023/7/15 13:51 */ public class AmericanoCoffee extends Coffee { }

package top.simba1949.factory.method.coffee; import lombok.Data; import lombok.extern.slf4j.Slf4j; /** * @author anthony * @datetime 2023/7/15 13:53 */ @Slf4j @Data public class LatteCoffee extends Coffee { }

工厂类

package top.simba1949.factory.method.factory; import top.simba1949.factory.method.coffee.Coffee; /** * @author anthony * @datetime 2023/7/15 13:48 */ public abstract class CoffeeFactory { public abstract Coffee createCoffee(); }

package top.simba1949.factory.method.factory; import lombok.extern.slf4j.Slf4j; import top.simba1949.factory.method.coffee.AmericanoCoffee; import top.simba1949.factory.method.coffee.Coffee; /** * @author anthony * @datetime 2023/7/15 13:49 */ @Slf4j public class AmericanoCoffeeFactory extends CoffeeFactory { @Override public Coffee createCoffee() { Coffee coffee = new AmericanoCoffee(); coffee.setName("美式咖啡"); return coffee; } }

package top.simba1949.factory.method.factory; import lombok.extern.slf4j.Slf4j; import top.simba1949.factory.method.coffee.Coffee; import top.simba1949.factory.method.coffee.LatteCoffee; /** * @author anthony * @datetime 2023/7/15 13:49 */ @Slf4j public class LatteCoffeeFactory extends CoffeeFactory { @Override public Coffee createCoffee() { Coffee coffee = new LatteCoffee(); coffee.setName("拿铁咖啡"); return coffee; } }

咖啡店

package top.simba1949.factory.method; import lombok.Data; import lombok.extern.slf4j.Slf4j; import top.simba1949.factory.method.coffee.Coffee; import top.simba1949.factory.method.factory.CoffeeFactory; /** * @author anthony * @datetime 2023/7/15 13:52 */ @Slf4j @Data public class CoffeeStore { public CoffeeFactory coffeeFactory; public Coffee orderCoffee(){ // 这里创建对应的对象 Coffee coffee = coffeeFactory.createCoffee(); coffee.addMilk(); coffee.addSugar(); return coffee; } }

测试类

package top.simba1949.factory.method; import lombok.extern.slf4j.Slf4j; import top.simba1949.factory.method.coffee.Coffee; import top.simba1949.factory.method.factory.AmericanoCoffeeFactory; import top.simba1949.factory.method.factory.CoffeeFactory; /** * @author anthony * @datetime 2020/5/9 14:30 */ @Slf4j public class MethodFactoryApplication { public static void main(String[] args) { // 创建咖啡店对象 CoffeeStore coffeeStore = new CoffeeStore(); // 创建工厂对象 CoffeeFactory coffeeFactory = new AmericanoCoffeeFactory(); coffeeStore.setCoffeeFactory(coffeeFactory); // 订购咖啡 Coffee coffee = coffeeStore.orderCoffee(); log.info("订购的咖啡是:{}", coffee); } }抽象工厂模式

是一种为访问类提供一个创建一组相关或者相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同组的不同等级的产品的模式结构。
抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂可生产多个等级的产品。

抽象工厂模式的主要角色抽象工厂模式的优缺点

优点

当一个产品族中的多个对象被设计成一起工作时,他能保证客户端始终只使用同一个产品族中的对象;

缺点

当产品族中需要新增一个新的产品,所有的工厂类都需要进行修改;

使用场景

如:输入法换皮肤,一整套一起换。生成不同操作系统的程序。

抽象工厂模式的实现

UML

通俗理解工厂模式,工厂模式三种详解(2)


甜点

package top.simba1949.factory.abs.dessert; import lombok.Data; import lombok.extern.slf4j.Slf4j; /** * @author anthony * @datetime 2023/7/15 14:25 */ @Slf4j @Data public abstract class Dessert { private String name; public void show() { log.info("正在展示的甜点是{}", name); } }

package top.simba1949.factory.abs.dessert; /** * 抹茶慕斯 * * @author anthony * @datetime 2023/7/15 14:28 */ public class MatchaMousseDessert extends Dessert{ }

package top.simba1949.factory.abs.dessert; /** * 提拉米苏 * * @author anthony * @datetime 2023/7/15 14:26 */ public class TiramisuDessert extends Dessert { }

咖啡

package top.simba1949.factory.abs.coffee; import lombok.Data; import lombok.extern.slf4j.Slf4j; /** * @author anthony * @datetime 2023/7/15 14:26 */ @Slf4j @Data public abstract class Coffee { private String name; public void addMilk(){ log.info("{} 添加了牛奶", name); } public void addSugar(){ log.info("{} 添加了糖", name); } }

package top.simba1949.factory.abs.factory; import lombok.extern.slf4j.Slf4j; import top.simba1949.factory.abs.coffee.AmericanoCoffee; import top.simba1949.factory.abs.coffee.Coffee; import top.simba1949.factory.abs.dessert.Dessert; import top.simba1949.factory.abs.dessert.MatchaMousseDessert; /** * @author anthony * @datetime 2023/7/15 14:32 */ @Slf4j public class AmericanFactory extends AbsFactory { @Override public Coffee createCoffee() { Coffee coffee = new AmericanoCoffee(); coffee.setName("美式咖啡"); coffee.addSugar(); return coffee; } @Override public Dessert createDessert() { Dessert dessert = new MatchaMousseDessert(); dessert.setName("抹茶慕斯"); return dessert; } }

package top.simba1949.factory.abs.factory; import lombok.extern.slf4j.Slf4j; import top.simba1949.factory.abs.coffee.Coffee; import top.simba1949.factory.abs.coffee.LatteCoffee; import top.simba1949.factory.abs.dessert.Dessert; import top.simba1949.factory.abs.dessert.TiramisuDessert; /** * @author anthony * @datetime 2023/7/15 14:32 */ @Slf4j public class ItalyFactory extends AbsFactory { @Override public Coffee createCoffee() { Coffee coffee = new LatteCoffee(); coffee.setName("拿铁咖啡"); coffee.addMilk(); return coffee; } @Override public Dessert createDessert() { Dessert dessert = new TiramisuDessert(); dessert.setName("提拉米苏"); return dessert; } }

工厂

package top.simba1949.factory.abs.factory; import top.simba1949.factory.abs.coffee.Coffee; import top.simba1949.factory.abs.dessert.Dessert; /** * @author anthony * @datetime 2023/7/15 14:31 */ public abstract class AbsFactory { public abstract Coffee createCoffee(); public abstract Dessert createDessert(); }

package top.simba1949.factory.abs.factory; import lombok.extern.slf4j.Slf4j; import top.simba1949.factory.abs.coffee.AmericanoCoffee; import top.simba1949.factory.abs.coffee.Coffee; import top.simba1949.factory.abs.dessert.Dessert; import top.simba1949.factory.abs.dessert.MatchaMousseDessert; /** * @author anthony * @datetime 2023/7/15 14:32 */ @Slf4j public class AmericanFactory extends AbsFactory { @Override public Coffee createCoffee() { Coffee coffee = new AmericanoCoffee(); coffee.setName("美式咖啡"); coffee.addSugar(); return coffee; } @Override public Dessert createDessert() { Dessert dessert = new MatchaMousseDessert(); dessert.setName("抹茶慕斯"); return dessert; } }

package top.simba1949.factory.abs.factory; import lombok.extern.slf4j.Slf4j; import top.simba1949.factory.abs.coffee.Coffee; import top.simba1949.factory.abs.coffee.LatteCoffee; import top.simba1949.factory.abs.dessert.Dessert; import top.simba1949.factory.abs.dessert.TiramisuDessert; /** * @author anthony * @datetime 2023/7/15 14:32 */ @Slf4j public class ItalyFactory extends AbsFactory { @Override public Coffee createCoffee() { Coffee coffee = new LatteCoffee(); coffee.setName("拿铁咖啡"); coffee.addMilk(); return coffee; } @Override public Dessert createDessert() { Dessert dessert = new TiramisuDessert(); dessert.setName("提拉米苏"); return dessert; } }

测试

package top.simba1949.factory.abs; import lombok.extern.slf4j.Slf4j; import top.simba1949.factory.abs.coffee.Coffee; import top.simba1949.factory.abs.dessert.Dessert; import top.simba1949.factory.abs.factory.ItalyFactory; /** * @author anthony * @datetime 2023/7/15 14:37 */ @Slf4j public class AbsFactoryApplication { public static void main(String[] args) { ItalyFactory italyFactory = new ItalyFactory(); Coffee coffee = italyFactory.createCoffee(); log.info("订购的咖啡是:{}", coffee); Dessert dessert = italyFactory.createDessert(); log.info("订购的甜品是:{}", dessert); } } JDK 源码中的工厂模式

Calendar instance = Calendar.getInstance(); public static Calendar getInstance() { return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT)); } private static Calendar createCalendar(TimeZone zone, Locale aLocale) { CalendarProvider provider = LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale).getCalendarProvider(); if (provider != null) { try { return provider.getInstance(zone, aLocale); } catch (IllegalArgumentException iae) { // fall back to the default instantiation } } // 根据不同的入参,返回不同的Calendar子类 Calendar cal = null; if (aLocale.hasExtensions()) { String caltype = aLocale.getUnicodeLocaleType("ca"); if (caltype != null) { switch (caltype) { case "buddhist": cal = new BuddhistCalendar(zone, aLocale); break; case "japanese": cal = new JapaneseImperialCalendar(zone, aLocale); break; case "gregory": cal = new GregorianCalendar(zone, aLocale); break; } } } if (cal == null) { // If no known calendar type is explicitly specified, // perform the traditional way to create a Calendar: // create a BuddhistCalendar for th_TH locale, // a JapaneseImperialCalendar for ja_JP_JP locale, or // a GregorianCalendar for any other locales. // NOTE: The language, country and variant strings are interned. if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") { cal = new BuddhistCalendar(zone, aLocale); } else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja" && aLocale.getCountry() == "JP") { cal = new JapaneseImperialCalendar(zone, aLocale); } else { cal = new GregorianCalendar(zone, aLocale); } } return cal; }

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.