工厂模式

我们先看一个具体需求

看一个披萨的项目:要便于披萨种类的扩展,要便于维护
1)披萨的种类很多(比如GreekPizz(希腊)、CheesePizz (奶酪)等)
2)披萨的制作有prepare(准备材料), bake(烘烤), cut(切割), box(打包)
3)完成披萨店订购功能。

传统方式怎么做?

代码

Pizza抽象类

/*** @author 王庆华* @version 1.0* @date 2020/12/21 20:06* @Description TODO* @pojectname 披萨抽象类    设置为抽象类*/
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种类

public class CheesePizza extends Pizza {@Overridepublic void prepare() {System.out.println("准备制作奶酪披萨的原材料");}
}
public class GreekPizza extends Pizza {@Overridepublic void prepare() {System.out.println("给希腊披萨准备原材料");}
}

订单发起类

/*** @author 王庆华* @version 1.0* @date 2020/12/21 20:14* @Description TODO* @pojectname 订购披萨代码*/
public class OrderPizza {//构造器public OrderPizza() {Pizza pizza = null;String orderType;//订购披萨类型是什么do {orderType = getType();if (orderType.equals("greek")){pizza = new GreekPizza();pizza.setName("希腊披萨");}else if (orderType.equals("cheese")){pizza = new CheesePizza();pizza.setName("奶酪披萨");}else {break;}//输出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 "";}}
}

主类:披萨店

/*** @author 王庆华* @version 1.0* @date 2020/12/21 20:22* @Description TODO* @pojectname 披萨店客户端,发起订购的类(主类)*/
public class PizzaStore {public static void main(String[] args) {OrderPizza orderPizza = new OrderPizza();}
}

优点和存在的问题

优点是比较好理解,简单易操作。
缺点是违反了设计模式的ocp原则,即对扩展开放,对修改关闭。即当我们给类增加新功能的时候,尽量不修改代码,或者尽可能少修改代码

比如我们这时要新增加一个Pizza的种类(Pepper披萨),我们需要做如下修改:

1.增加胡椒披萨,继承抽象披萨类

public class PepperPizza extends Pizza {@Overridepublic void prepare() {System.out.println("给胡椒披萨准备原材料");}
}

2.我们就必须在OrderPizza中加入判断是不是胡椒披萨的逻辑

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("胡椒披萨");
} else {break;
}

加入我们分店多,OrderPizza有2,3,4,5,6……呢?岂不是每个都要改?

改进

分析:修改代码可以接受,但是如果我们在其它的地方也有创建Pizza的代码,就意味着,也需要修改,而创建Pizza的代码,往往有多处。
**思路:**把创建Pizza对象封装到-一个类中,这样我们有新的Pizza种类时,只需要修改该类就可,其它有创建到Pizza对象的代码就不需要修改了====>简单工厂模式

简单工厂模式

基本介绍

又称静态工厂模式

1)简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产 品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式

2)简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)

3)在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式.

代码

/*** @author 王庆华* @version 1.0* @date 2020/12/21 20:43* @Description TODO* @pojectname 简单工厂用来管理Pizza的生产*/
public class SimpleFactory {/*** 根据我们的pizza类型,返回一个该类型的实例对象* @param orderType pizza类型* @return*/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的变化

/*** @author 王庆华* @version 1.0* @date 2020/12/21 20:14* @Description TODO* @pojectname 订购披萨代码*/
public class OrderPizza {//定义简单工厂对象SimpleFactory simpleFactory;Pizza pizza = null;public void setSimpleFactory(SimpleFactory simpleFactory) {String orderType = "";//orderType用户输入pizza类型this.simpleFactory = simpleFactory;//设置一个简单工厂对象do {orderType = getType();//获取用户订购的pizza类型pizza = this.simpleFactory.createPizza(orderType);//输出制作pizza信息if (pizza != null){//订购成功pizza.prepare();pizza.bake();pizza.cut();pizza.box();}else {System.out.println("预定失败,请检查是不是没有这个pizza类型");break;}}while(true);}//构造器public OrderPizza(SimpleFactory simpleFactory){setSimpleFactory(simpleFactory);}//获取客户订购的披萨种类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 "";}}}

客户端的变化

/*** @author 王庆华* @version 1.0* @date 2020/12/21 20:22* @Description TODO* @pojectname 披萨店客户端,发起订购的类(主类)*/
public class PizzaStore {public static void main(String[] args) {//使用简单工厂模式订购new OrderPizza(new SimpleFactory());System.out.println("退出程序");}
}

我们来理解一下:首先我们new不同Pizza种类的代码,从OrderPizza中转移到了简单工厂模式,这样以后我们还要增加披萨种类的时候,就不用去管那么多的OrderPizza了,只需要在工厂模式中增加一个逻辑判断就行了,而且这个工厂是扩展方,符合了我们OOP的思想

在我们的OrderPizza中,引入了一个直接朋友简单工厂对象,由这个简单工厂对象给我们生产Pizza,我们的OrderPizza只需要拿到这个对象就行了,并不需要自己再去new了,符合修改关闭

更加方便的是,我们可以把简单工厂模式中的createPizza方法设置为静态方法,那我们的代码会变成什么呢?

简单工厂模式的变化只是把createPizza方法加static修饰

OrderPizza改变

package com.wang.factory.pizza.order;
import com.wang.factory.pizza.Pizza;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/*** @author 王庆华* @version 1.0* @date 2020/12/21 20:14* @Description TODO* @pojectname 订购披萨代码*/
public class OrderPizza2 {Pizza pizza = null;String orderType = "";//orderType用户输入pizza类型//构造器public OrderPizza2(){do {orderType = getType();//获取用户订购的pizza类型pizza = SimpleFactory.createPizza(orderType);//输出制作pizza信息if (pizza != null){//订购成功pizza.prepare();pizza.bake();pizza.cut();pizza.box();}else {System.out.println("预定失败,请检查是不是没有这个pizza类型");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 "";}}
}

因为我们的createPizza变成静态模式了,我们就不需要在传递一个简单工厂对象了,可以直接通过类名调用,就不在需要set一个简单工厂对象了

两者差距不大,细节之处在于不是静态方法的时候,容易根据需求creat,效果相差不大,看业务需求

Java设计模式----工厂模式-----简单工厂(静态工厂模式)相关推荐

  1. Java 9 JShell示例:集合静态工厂方法

    这篇文章继续了My My Java 9 Features博客文章中对Java9功能的探索. 在这里,我们在List,Set和Map接口中试验Java9 Collections静态工厂方法. 集合静态工 ...

  2. Java设计模式之行为型:责任链模式

    背景: 学校规定参加校招的同学必须要请假,且要有相关人员的签字,三天以下需辅导员签字.三到七天需要系主任签字,一个星期以上需要院长签字,更多的则需要校长签字! 上图将学生.辅导员.系主任.院长.校长组 ...

  3. Java设计模式之结构型:享元模式

    一.什么是享元模式: 享元模式通过共享技术有效地支持细粒度.状态变化小的对象复用,当系统中存在有多个相同的对象,那么只共享一份,不必每个都去实例化一个对象,极大地减少系统中对象的数量.比如说一个文本系 ...

  4. Java设计模式之结构型:装饰器模式

    一.什么是装饰器模式: 当需要对类的功能进行拓展时,一般可以使用继承,但如果需要拓展的功能种类很繁多,那势必会生成很多子类,增加系统的复杂性,并且使用继承实现功能拓展时,我们必须能够预见这些拓展功能, ...

  5. Java设计模式(7)装饰模式(Decorator模式)

    Decorator常被翻译成"装饰",我觉得翻译成"油漆工"更形象点,油漆工(decorator)是用来刷油漆的,那么被刷油漆的对象我们称decoratee.这 ...

  6. Java设计模式之行为型:中介者模式

     前言: 在我们的生活中处处充斥着"中介者",比如你租房.买房.找工作.旅游等等可能都需要那些中介者的帮助,地球上国与国之间的关系异常复杂,会因为各种各样的利益关系来结成盟友或者敌 ...

  7. 【每天一个java设计模式(二十三)】 - 访问者模式

    在访问者模式中,我们使用了一个访问者类,它改变了元素类的执行算法.通过这种方式,元素的执行算法可以随着访问者改变而改变.这种类型的设计模式属于行为型模式.根据模式,元素对象已接受访问者对象,这样访问者 ...

  8. 【每天一个java设计模式(十五)】 - 命令模式

    命令模式是一种数据驱动的设计模式,它属于行为型模式.请求以命令的形式包裹在对象中,并传给调用对象.调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令. 命令模式也就是一个 ...

  9. 【每天一个java设计模式(十四)】 - 解释器模式

    解释器模式提供了评估语言的语法或表达式的方式,它属于行为型模式.这种模式实现了一个表达式接口,该接口解释一个特定的上下文. 解释器模式主要包括以下几个部分: 抽象表达式角色:定义解释器的接口,约定解释 ...

  10. JAVA设计模式是个什么玩意儿_00_工厂模式家族准备篇_简单工厂模式

    1. 前言 又叫静态工厂方法(Static Factory Method)模式. 它并不是GoF那23种设计模式之一. 简单工厂模式是工厂模式家族中最简单实用的模式. 虽然很简单,但它是学习工厂方法模 ...

最新文章

  1. css3之transition、transform、animation比较
  2. vs2010连接mongodb服务器,X64位
  3. 常见的基于node.js的web框架
  4. 【转】jmeter响应结果乱码问题
  5. Java读取多层级xml文件
  6. Ppt2010中HTML是什么,2010dw1html简介.ppt
  7. 光大银行刘淼:基于华为云GaussDB(DWS) 数据仓库创新实践
  8. 计算机知识点背诵了就忘了怎么办,背得滚瓜烂熟的知识点,为什么一上考场全忘了?这样做,事半功倍…...
  9. C/C++指针数组与数组指针彻底搞明白
  10. mven2 + androMDA 初探
  11. 静态的通讯录(C语言)
  12. (二十)美萍酒店管理系统:系统维护_系统设置_房间类型_单个添加、多个添加
  13. MySQL 去重SQL
  14. SEO培训联盟排名掉的原因:宋星博客?
  15. 基础//页面布局——三栏布局1
  16. SuperMap iClient for MapboxGL 实现WFS查询功能
  17. 3366 打豆豆 瞄准线 源码程序
  18. 在抖音里添加商品图有水印该怎么去,在抖音里添加商品从别人那里下载的商品图有水印怎么办,抖音商品图怎么去水印
  19. 成长的模式:如何从毕业生到技术专家?
  20. 【RSA原理1】浅谈--什么是非对称加密?(加密通信的原理)

热门文章

  1. java工程师面试几百问_不是吧?面试被问了几百遍的JVM,你还搞不清楚?
  2. 充电枪cp信号控制板_比亚迪E5无法交流充电故障检修
  3. python定义私有变量的方法_Python中私有属性的定义方式
  4. java list判断是否存在字符串_java怎么判断字符串是否存在于list集合中?
  5. 深度学习笔记_基本概念_Depthwise卷积与Pointwise卷积
  6. 类的继承与派生的基础学习
  7. Canny算法解析,opencv源码实现及实例
  8. 疫情严峻!有高校不放寒假,直接开始新学期!还有高校紧急放假,停止考试直接回家...
  9. XGBoost算法解析(非常详细)
  10. 【linux基础】linux不能进入系统