看一个具体的需求
看一个披萨的项目:要便于披萨种类的扩展,要便于维护
1) 披萨的种类很多(比如 GreekPizz、CheesePizz 等)
2) 披萨的制作有 prepare,bake, cut, box 3) 完成披萨店订购功能
传统代码就省略了
传统的方式的优缺点
1) 优点是比较好理解,简单易操作。
2) 缺点是违反了设计模式的ocp原则,即对扩展开放,对修改关闭。即当我们给类增 加新功能的时候,尽量不修改代码,或者尽可能少修改代码.
3) 比如我们这时要新增加一个Pizza的种类(Pepper披萨),我们需要做修改
改进的思路分析
分析:修改代码可以接受,但是如果我们在其它的地方也有创建Pizza的代码,就意味 着,也需要修改,而创建Pizza的代码,往往有多处。
思路:把创建Pizza对象封装到一个类中,这样我们有新的Pizza种类时,只需要修改该 类就可,其它有创建到Pizza对象的代码就不需要修改了.-> 简单工厂模式
简单工厂模式
Pizza抽象类
package com.wang.factory.simplefactory.pizzastore.pizza; public abstract class Pizza { protected String name; //名字 //准备原材料, 不同的披萨不一样,因此,我们做成抽象方法 public abstract void prepare(); public void bake() { System.out.println(name + " baking;"); } public void cut() { System.out.println(name + " cutting;"); } //打包 public void box() { System.out.println(name + " boxing;"); } public void setName(String name) { this.name = name; } }
Pizza抽象类子类PepperPizza
package com.wang.factory.simplefactory.pizzastore.pizza; public class PepperPizza extends Pizza { @Override public void prepare() { // TODO Auto-generated method stub System.out.println(" 给胡椒披萨准备原材料 "); } }
Pizza抽象类子类GreekPizza
package com.wang.factory.simplefactory.pizzastore.pizza; public class GreekPizza extends Pizza{ @Override public void prepare() { System.out.println(" 给希腊披萨 准备原材料 "); } }
Pizza抽象类子类GreekPizza
package com.wang.factory.simplefactory.pizzastore.pizza; public class CheesePizza extends Pizza{ @Override public void prepare() { System.out.println(" 给奶酪披萨 准备原材料 "); } }
简单工厂类SimpleFactory
package com.wang.factory.simplefactory.pizzastore.order; import com.wang.factory.simplefactory.pizzastore.pizza.CheesePizza; import com.wang.factory.simplefactory.pizzastore.pizza.GreekPizza; import com.wang.factory.simplefactory.pizzastore.pizza.PepperPizza; import com.wang.factory.simplefactory.pizzastore.pizza.Pizza; public class SimpleFactory { public Pizza createPizza(String orderType){ Pizza pizza = null; System.out.println("使用简单工厂模式"); if (orderType.equals("greek")) { pizza = new GreekPizza(); pizza.setName(" 希腊披萨 "); } else if (orderType.equals("cheese")) { pizza = new CheesePizza(); pizza.setName(" 奶酪披萨 "); } else if (orderType.equals("pepper")) { pizza = new PepperPizza(); pizza.setName("胡椒披萨"); } return pizza; } }
订单类OrderPizza
package com.wang.factory.simplefactory.pizzastore.order; import com.wang.factory.simplefactory.pizzastore.pizza.CheesePizza; import com.wang.factory.simplefactory.pizzastore.pizza.GreekPizza; import com.wang.factory.simplefactory.pizzastore.pizza.PepperPizza; import com.wang.factory.simplefactory.pizzastore.pizza.Pizza; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class OrderPizza { SimpleFactory simpleFactory; Pizza pizza=null; public OrderPizza(SimpleFactory simpleFactory) { //this.simpleFactory=simpleFactory; setFactory(simpleFactory); } public void setFactory(SimpleFactory simpleFactory) { String orderType = ""; //用户输入的 this.simpleFactory=simpleFactory; do { orderType = getType(); pizza = this.simpleFactory.createPizza(orderType); //输出pizza if(pizza != null) { //订购成功 pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } else { System.out.println(" 订购披萨失败 "); break; } }while(true); } // 写一个方法,可以获取客户希望订购的披萨种类 private String getType() { try { BufferedReader strin = new BufferedReader(new InputStreamReader(System.in)); System.out.println("input pizza 种类:"); String str = strin.readLine(); return str; } catch (IOException e) { e.printStackTrace(); return ""; } } }
披萨商店类PizzaStore,相当于客户端
package com.wang.factory.simplefactory.pizzastore.order; //相当于一个客户端,发出订购 public class PizzaStore { public static void main(String[] args) { //new OrderPizza(); new OrderPizza(new SimpleFactory()); } }
工厂方法模式
看一个新的需求 披萨项目新的需求:客户在点披萨时,可以点不同口味的披萨,比如 北京的奶酪pizza、 北京的胡椒pizza 或者是伦敦的奶酪pizza、伦敦的胡椒pizza。
思路1 使用简单工厂模式,创建不同的简单工厂类,比如BJPizzaSimpleFactory、 LDPizzaSimpleFactory 等等.从当前这个案例来说,也是可以的,但是考虑到项目的 规模,以及软件的可维护性、可扩展性并不是特别好
思路2 使用工厂方法模式
工厂方法模式介绍 工厂方法模式设计方案:将披萨项目的实例化功能抽象成抽象方法,在不同的口味点 餐子类中具体实现。
工厂方法模式:定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方 法模式将对象的实例化推迟到子类。
工厂方法模式应用案例 披萨项目新的需求:客户在点披萨时,可以点不同口味的披萨,比如 北京的奶酪 pizza、北京的胡椒pizza 或者是伦敦的奶酪pizza、伦敦的胡椒pizza
披萨类代码同简单工厂模式
披萨订单类OrderPizza
package com.wang.factory.factorymethod.pizzastore.order; import com.wang.factory.factorymethod.pizzastore.pizza.Pizza; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public abstract class OrderPizza { //定义一个抽象方法,createPizza , 让各个工厂子类自己实现 abstract Pizza createPizza(String orderType); public OrderPizza(){ String orderType; Pizza pizza=null; do { orderType=getType(); pizza=createPizza(orderType); //输出pizza 制作过程 pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); }while (true); } // 写一个方法,可以获取客户希望订购的披萨种类 private String getType() { try { BufferedReader strin = new BufferedReader(new InputStreamReader(System.in)); System.out.println("input pizza 种类:"); String str = strin.readLine(); return str; } catch (IOException e) { e.printStackTrace(); return ""; } } }
披萨订单类OrderPizza的实现类BJOrderPizza
package com.wang.factory.factorymethod.pizzastore.order; import com.wang.factory.factorymethod.pizzastore.pizza.BJCheesePizza; import com.wang.factory.factorymethod.pizzastore.pizza.BJPepperPizza; import com.wang.factory.factorymethod.pizzastore.pizza.Pizza; public class BJOrderPizza extends OrderPizza { @Override Pizza createPizza(String orderType) { Pizza pizza = null; if(orderType.equals("cheese")) { pizza = new BJCheesePizza(); } else if (orderType.equals("pepper")) { pizza = new BJPepperPizza(); } return pizza; } }
披萨订单类OrderPizza的实现类LDOrderPizza
package com.wang.factory.factorymethod.pizzastore.order; import com.wang.factory.factorymethod.pizzastore.pizza.LDCheesePizza; import com.wang.factory.factorymethod.pizzastore.pizza.LDPepperPizza; import com.wang.factory.factorymethod.pizzastore.pizza.Pizza; public class LDOrderPizza extends OrderPizza { @Override Pizza createPizza(String orderType) { Pizza pizza = null; if(orderType.equals("cheese")) { pizza = new LDCheesePizza(); } else if (orderType.equals("pepper")) { pizza = new LDPepperPizza(); } // TODO Auto-generated method stub return pizza; } }
PizzaStore商店类
package com.wang.factory.factorymethod.pizzastore.order; public class PizzaStore { public static void main(String[] args) { new BJOrderPizza(); } }
抽象工厂模式
基本介绍
1) 抽象工厂模式:定义了一个interface用于创建相关或有依赖关系的对象簇,而无需 指明具体的类
2) 抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。
3) 从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)。
4) 将工厂抽象成两层,AbsFactory(抽象工厂) 和 具体实现的工厂子类。程序员可以 根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇, 更利于代码的维护和扩展。
一个抽象工厂模式的抽象层(接口)
package com.wang.factory.absfactory.pizzastore.order; import com.wang.factory.absfactory.pizzastore.pizza.Pizza; //一个抽象工厂模式的抽象层(接口) public interface AbsFactory { //让下面的工厂子类来 具体实现 public Pizza createPizza(String orderType); }
工厂子类BJFactory
package com.wang.factory.absfactory.pizzastore.order; import com.wang.factory.absfactory.pizzastore.pizza.BJCheesePizza; import com.wang.factory.absfactory.pizzastore.pizza.BJPepperPizza; import com.wang.factory.absfactory.pizzastore.pizza.Pizza; //这是工厂子类 public class BJFactory implements AbsFactory { @Override public Pizza createPizza(String orderType) { System.out.println("~使用的是抽象工厂模式~"); // TODO Auto-generated method stub Pizza pizza = null; if(orderType.equals("cheese")) { pizza = new BJCheesePizza(); } else if (orderType.equals("pepper")){ pizza = new BJPepperPizza(); } return pizza; } }
工厂子类LDFactory
package com.wang.factory.absfactory.pizzastore.order; import com.wang.factory.absfactory.pizzastore.pizza.LDCheesePizza; import com.wang.factory.absfactory.pizzastore.pizza.LDPepperPizza; import com.wang.factory.absfactory.pizzastore.pizza.Pizza; public class LDFactory implements AbsFactory { @Override public Pizza createPizza(String orderType) { System.out.println("~使用的是抽象工厂模式~"); Pizza pizza = null; if (orderType.equals("cheese")) { pizza = new LDCheesePizza(); } else if (orderType.equals("pepper")) { pizza = new LDPepperPizza(); } return pizza; } }
订单类OrderPizza
package com.wang.factory.absfactory.pizzastore.order; import com.wang.factory.absfactory.pizzastore.pizza.Pizza; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class OrderPizza { AbsFactory factory; // 构造器 public OrderPizza(AbsFactory factory) { setFactory(factory); } private void setFactory(AbsFactory factory) { Pizza pizza = null; String orderType = ""; // 用户输入 this.factory = factory; do { orderType = getType(); // factory 可能是北京的工厂子类,也可能是伦敦的工厂子类 pizza = factory.createPizza(orderType); if (pizza != null) { // 订购ok pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } else { System.out.println("订购失败"); break; } } while (true); } // 写一个方法,可以获取客户希望订购的披萨种类 private String getType() { try { BufferedReader strin = new BufferedReader(new InputStreamReader(System.in)); System.out.println("input pizza 种类:"); String str = strin.readLine(); return str; } catch (IOException e) { e.printStackTrace(); return ""; } } }
商店类
public class PizzaStore { public static void main(String[] args) { // TODO Auto-generated method stub //new OrderPizza(new BJFactory()); new OrderPizza(new LDFactory()); } }
工厂模式在JDK-Calendar 应用的源码分析
根据TimeZone zone,Locale aLocale创建对应的日历
工厂模式小结
1) 工厂模式的意义 将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的 依赖关系的解耦。从而提高项目的扩展和维护性。
2) 三种工厂模式 (简单工厂模式、工厂方法模式、抽象工厂模式)
3) 设计模式的依赖抽象原则
创建对象实例时,不要直接 new 类, 而是把这个new 类的动作放在一个工厂的方法 中,并返回。有的书上说,变量不要直接持有具体类的引用。
不要让类继承具体类,而是继承抽象类或者是实现interface(接口) 不要覆盖基类中已经实现的方法。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!