工厂模式-依赖倒置原则

老板:阿飞啊,我们公司最近接了个项目,你看着设计一下,我给你说下需求。
项目组长阿飞:好啊,什么需求?
老板:我们找了一个合作的商铺,他们要设计一套面包销售系统。主要功能,根据用户选择的面包种类来下订单,面包目前有奶油口味面包和苹果口味面包,所有面包的制作流程都是---搅拌,搓圆,加工,烘烤。
项目组长阿飞:好的,我去想想怎么设计。
项目组长阿飞:小三啊,我给你个任务,…………,听懂了吗?
阿三:听懂了,飞哥。
项目组长阿飞:嗯嗯,好的,这个任务就交给你了,我要去处理点事情,我相信你。
阿三:。。。
三天过后。
阿三:飞哥,设计好了,你看下。

 1 package com.factoryPattern.factory;
 2 
 3 /**
 4  * @program: designPattern
 5  * @description: 面包口味的抽象类
 6  * @author: Mr.Yang
 7  * @create: 2018-11-18 19:24
 8  **/
 9 public abstract class BreadFactory {
10     protected String name;
11     protected String type;
12 
13     public BreadFactory stir(){
14         System.out.println("搅拌");
15         return this;
16     }
17 
18     public BreadFactory rubbingRound(){
19         System.out.println("搓圆");
20         return this;
21     }
22 
23     public BreadFactory machining(){
24         System.out.println("加工");
25         return this;
26     }
27     public BreadFactory bake(){
28         System.out.println("烘烤");
29         return this;
30     }
31 
32     public String getName() {
33         return name;
34     }
35 
36     public BreadFactory setName(String name) {
37         this.name = name;
38         return this;
39     }
40 
41     public String getType() {
42         return type;
43     }
44 
45     public BreadFactory setType(String type) {
46         this.type = type;
47         return this;
48     }
49 }
View Code
 

现在已有的两种口味继承这个抽象类--奶油面包

 package com.factoryPattern.breadKind;import com.factoryPattern.breadKind.factory.BreadFactory;/*** @program: designPattern* @description: 奶油味面包* @author: Mr.Yang* @create:**/
public class CreamBread extends BreadFactory {public CreamBread(){name="奶油味";type="2";}//可以重写父类方法,进行特殊处理
}
View Code
 

苹果味面包

 1  package com.factoryPattern.breadKind;
 2  
 3  import com.factoryPattern.breadKind.factory.BreadFactory;
 4  
 5  /**
 6   * @program: designPattern
 7   * @description: 苹果味面包
 8   * @author: Mr.Yang
 9   * @create:
10  **/
11 public class AppleBread extends BreadFactory {
12     public AppleBread(){
13         name="苹果味";
14         type="1";
15     }
16     //可以重写父类方法,进行特殊处理
17 }
View Code
 

然后是销售系统

 1  package com.factoryPattern.breadKind.breadOrder;
 2  
 3  import com.factoryPattern.breadKind.AppleBread;
 4  import com.factoryPattern.breadKind.CreamBread;
 5  import com.factoryPattern.breadKind.factory.BreadFactory;
 6  
 7  /**
 8   * @program: designPattern
 9   * @description: 面包订单销售类
10  * @author: Mr.Yang
11  * @create:
12  **/
13 public class BreadOrder {
14 
15 
16     BreadFactory orderBread(String type){
17         BreadFactory breadFactory;
18         if("cream".equalsIgnoreCase(type)){
19             System.out.println("创建奶油口味面包");
20             breadFactory=new CreamBread();
21         }else if("apple".equalsIgnoreCase(type)){
22             System.out.println("创建苹果口味面包");
23             breadFactory=new AppleBread();
24         }else{
25             System.out.println("无法确认的面包类型");
26             return null;
27         }
28 
29         return breadFactory.stir()
30                 .rubbingRound()
31                 .machining()
32                 .bake();
33     }
34 }
View Code
 

项目组长阿飞:三啊,不错,学会使用抽象了,但是如果我还要增加好几种面包类型呢?阿尔法面包销售不好,不想做这个了呢?之前给你说过设计模式的原则之一,对拓展开放,对修改关闭。如果有改动,可能会一直在这个代码的基础上累加做修改的。最好把创建对象的代码与销售的代码分隔开。 
阿三:好的,我再修改修改(真的是,搞这么麻烦干嘛!)
又三天过后。
阿三:飞哥,修改好了,你看下。

新增了一个工程类

 1  package com.factoryPattern.breadCreate;
 2  
 3  import com.factoryPattern.breadKind.AppleBread;
 4  import com.factoryPattern.breadKind.CreamBread;
 5  import com.factoryPattern.breadKind.factory.BreadFactory;
 6  
 7  /**
 8   * @program: designPattern
 9   * @description: 面包创建工程
10  * @author: Mr.Yang
11  * @create:
12  **/
13 public class BreadCreateFactory {
14     public BreadFactory createBread(String type){
15         BreadFactory breadFactory=null;
16         if("cream".equalsIgnoreCase(type)){
17             System.out.println("创建奶油口味面包");
18             breadFactory=new CreamBread();
19         }else if("apple".equalsIgnoreCase(type)){
20             System.out.println("创建苹果口味面包");
21             breadFactory=new AppleBread();
22         }else{
23             System.out.println("无法确认的面包类型");
24             return null;
25         }
26         return breadFactory;
27     }
28 }
View Code

修改了销售类

 1  package com.factoryPattern.breadKind.breadOrder;
 2  
 3  import com.factoryPattern.breadCreate.BreadCreateFactory;
 4  import com.factoryPattern.breadKind.factory.BreadFactory;
 5  
 6  /**
 7   * @program: designPattern
 8   * @description: 面包订单销售类
 9   * @author: Mr.Yang
10  * @create:
11  **/
12 public class BreadOrder {
13     BreadCreateFactory breadCreateFactory;
14 
15     public BreadOrder(BreadCreateFactory breadCreateFactory) {
16         this.breadCreateFactory = breadCreateFactory;
17     }
18 
19     BreadFactory orderBread(String type) {
20         return breadCreateFactory.createBread(type)
21                 .stir()
22                 .rubbingRound()
23                 .machining()
24                 .bake();
25     }
26 }
View Code
 

项目组长阿飞:不错,这是一个简单工厂,但是你要记住,这并不是一个设计模式,而是一个编程习惯,一个不错的编程习惯,简单工厂把全部的事情,在一个地方处理完了,工厂方法是创建一个框架,让子类决定如何实现。还有领导说需求变了,这个面包店开了分店,一个在泰国,一个在新加坡,你看着再修改下吧,你可以考虑加入工厂方法。 
阿三:好的(我服了,真的是****)
又三天过后。
阿三:飞哥,修改好了,这是完整代码,你看下。
先是一个面包商店抽象类

 1  package com.factoryPattern.breadStore;
 2  
 3  import com.factoryPattern.factory.BreadFactory;
 4  
 5  /**
 6   * @program: designPattern
 7   * @description: 面包商店抽象类
 8   * @author: Mr.Yang
 9   * @create: -- :
10  **/
11 public abstract class BreadStoreFactory {
12 
13     public BreadFactory orderBread(String type) {
14         return createBread(type)
15                 .stir()
16                 .rubbingRound()
17                 .machining()
18                 .bake();
19     }
20 
21     abstract BreadFactory createBread(String type);
22 }
View Code
 

创建一个中国店铺子类实现商店抽象类

 1 package com.factoryPattern.breadStore;
 2  
 3  import com.factoryPattern.factory.BreadFactory;
 4  import com.factoryPattern.kind.ChinaAppleBread;
 5  import com.factoryPattern.kind.ChinaCreamBread;
 6  
 7  /**
 8   * @program: designPattern
 9   * @description: 中国店铺子类
10  * @author: Mr.Yang
11  * @create: -- :
12  **/
13 public class ChinaStore extends BreadStoreFactory{
14     @Override
15     BreadFactory createBread(String type) {
16         BreadFactory breadFactory=null;
17         if("cream".equalsIgnoreCase(type)){
18             System.out.println("创建中国奶油口味面包");
19             breadFactory=new ChinaCreamBread();
20         }else if("apple".equalsIgnoreCase(type)){
21             System.out.println("创建中国苹果口味面包");
22             breadFactory=new ChinaAppleBread();
23         }else{
24             System.out.println("无法确认的面包类型");
25             return null;
26         }
27         return breadFactory;
28     }
29 }
View Code
 

创建一个新加坡店铺子类

 1 package com.factoryPattern.breadStore;
 2  
 3  import com.factoryPattern.factory.BreadFactory;
 4  import com.factoryPattern.kind.SingaporeAppleBread;
 5  import com.factoryPattern.kind.SingaporeCreamBread;
 6  
 7  /**
 8   * @program: designPattern
 9   * @description: 新加坡店铺子类
10  * @author: Mr.Yang
11  * @create: -- :
12  **/
13 public class SingaporeStore extends BreadStoreFactory {
14     @Override
15     BreadFactory createBread(String type) {
16         BreadFactory breadFactory=null;
17         if("cream".equalsIgnoreCase(type)){
18             System.out.println("创建新加坡奶油口味面包");
19             breadFactory=new SingaporeCreamBread();
20         }else if("apple".equalsIgnoreCase(type)){
21             System.out.println("创建新加坡苹果口味面包");
22             breadFactory=new SingaporeAppleBread();
23         }else{
24             System.out.println("无法确认的面包类型");
25             return null;
26         }
27         return breadFactory;
28     }
29 }
View Code

 

 

创建一个泰国店铺子类

 1  package com.factoryPattern.breadStore;
 2  
 3  import com.factoryPattern.factory.BreadFactory;
 4  import com.factoryPattern.kind.ThailandAppleBread;
 5  
 6  /**
 7   * @program: designPattern
 8   * @description: 泰国店铺子类
 9   * @author: Mr.Yang
10  * @create: -- :
11  **/
12 public class ThailandStore extends BreadStoreFactory {
13     @Override
14     BreadFactory createBread(String type) {
15         BreadFactory breadFactory=null;
16         if("cream".equalsIgnoreCase(type)){
17             System.out.println("创建泰国奶油口味面包");
18             breadFactory=new ThailandAppleBread();
19         }else if("apple".equalsIgnoreCase(type)){
20             System.out.println("创建泰国苹果口味面包");
21             breadFactory=new ThailandAppleBread();
22         }else{
23             System.out.println("无法确认的面包类型");
24             return null;
25         }
26         return breadFactory;
27     }
28 }
View Code

 

 

面包口味的抽象类

 1  package com.factoryPattern.factory;
 2  
 3  /**
 4   * @program: designPattern
 5   * @description: 面包口味的抽象类
 6   * @author: Mr.Yang
 7   * @create: -- :
 8   **/
 9  public abstract class BreadFactory {
10     protected String name;
11     protected String type;
12 
13     public BreadFactory stir(){
14         System.out.println("搅拌");
15         return this;
16     }
17 
18     public BreadFactory rubbingRound(){
19         System.out.println("搓圆");
20         return this;
21     }
22 
23     public BreadFactory machining(){
24         System.out.println("加工");
25         return this;
26     }
27     public BreadFactory bake(){
28         System.out.println("烘烤");
29         return this;
30     }
31 
32     public String getName() {
33         return name;
34     }
35 
36     public BreadFactory setName(String name) {
37         this.name = name;
38         return this;
39     }
40 
41     public String getType() {
42         return type;
43     }
44 
45     public BreadFactory setType(String type) {
46         this.type = type;
47         return this;
48     }
49 }
View Code

 

 

中国苹果口味面包

 1  package com.factoryPattern.kind;
 2  
 3  import com.factoryPattern.factory.BreadFactory;
 4  
 5  /**
 6   * @program: designPattern
 7   * @description: 中国苹果口味面包
 8   * @author: Mr.Yang
 9   * @create: -- :
10  **/
11 public class ChinaAppleBread  extends BreadFactory {
12     public ChinaAppleBread(){
13         name="中国苹果口味";
14         type="";
15     }
16     //可以重写父类方法,进行特殊处理
17 }
View Code
 

中国奶油口味面包

 1  package com.factoryPattern.kind;
 2  
 3  import com.factoryPattern.factory.BreadFactory;
 4  
 5  /**
 6   * @program: designPattern
 7   * @description: 中国奶油口味面包
 8   * @author: Mr.Yang
 9   * @create: -- :
10  **/
11 public class ChinaCreamBread extends BreadFactory {
12     public ChinaCreamBread(){
13         name="中国奶油口味";
14         type="";
15     }
16     //可以重写父类方法,进行特殊处理
View Code

 

 

还有新加坡苹果口味面包,新加坡奶油口味面包,泰国苹果口味面包,泰国奶油口味面包

测试类

 1  package com.factoryPattern.patternTest;
 2  
 3  import com.factoryPattern.breadStore.BreadStoreFactory;
 4  import com.factoryPattern.breadStore.ChinaStore;
 5  
 6  /**
 7   * @program: designPattern
 8   * @description: 测试类
 9   * @author: Mr.Yang
10  * @create: -- :
11  **/
12 public class Test {
13     public static void main(String[] args) {
14         System.out.println("中国顾客买苹果味道面包");
15         BreadStoreFactory chinaBreadStoreFactory = new ChinaStore();
16         chinaBreadStoreFactory.orderBread("apple");
17     }
18 }
View Code

 

 

测试结果

1 中国顾客买苹果味道面包
2 创建中国苹果口味面包
3 搅拌
4 搓圆
5 加工
6 烘烤
 

项目组长阿飞:看着不错,给我讲解一下吧。
阿三:我所用的是设计模式中的工厂模式,让子类决定该创建的对象是什么,来达到将对象创建的过程封装的目的。我简单的画了个图

 

 

阿三:大致如图,工程模式的定义:定义了一个创建对象的接口,但有子类决定要实例化的类是哪一个。工程方法让类把实例化推迟到子类

项目组长阿飞:很好,看来你已经掌握了工程模式的精髓,工程模式遵循了一个设计原则:“要依赖抽象,不要依赖具体实现。”,它有一个响亮的名字:“依赖倒置原则”。 你看你这两个图。创建者抽象BreadStoreFactory依赖与BreadFactory抽象类,面包的具体实现(chinaAppleBread,chinaCreamBread)依赖与BreadFactory抽象类,想要遵循依赖倒置原则,工程方法并非是唯一的,但是确是最有威力的技巧之一。

阿三:好的(我早就知道了---膨胀的一批)

 

转载于:https://www.cnblogs.com/yangxiaojie/p/10010284.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/395941.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

aws lambda_如何通过在本地模拟AWS Lambda来加速无服务器开发

aws lambdaby John McKim约翰麦金(John McKim) 如何通过在本地模拟AWS Lambda来加速无服务器开发 (How you can speed up serverless development by simulating AWS Lambda locally) Designing AWS Lambda functions can be a frustrating experience. Each time you make a …

(6)css盒子模型(基础下)

一、理解多个盒子模型之间的相互关系 现在大部分的网页都是很复杂的,原因是一个“给人用的”网页中是可能存在着大量的盒子,并且它们以各种关系相互影响着。 html与DOM的关系 详情了解“DOM” :http://baike.baidu.com/link?urlSeSj8sRDE-JZ…

easyui获取下拉框选中的文本值_Word中文本显示不全的常见3种情况及解决方法

在日常工作使用Word文档时,经常会遇到文本显示不全的情况,比如文本框或表格里的文本显示不全等情况,你一般是怎么操作呢?以下这3种常见情况你可能也遇到过,一起看看是什么原因并解决它们吧!1、文本显示不全…

企业IT架构转型之道:阿里巴巴中台战略思想与架构实战. 导读

企业IT架构转型之道 阿里巴巴中台战略思想与架构实战 钟 华 编 著 前 言  在过去15年的IT从业经历中,有很长一段时间我都是以软件服务商的身份参与了企业的IT系统建设,对于过去十几年来企业IT的发展有一定的认知和理解,带着对互联网技术…

计算机软件技术大作业报告,多媒体技术大作业报告.doc

多媒体技术大作业报告.doc华南理工大学多媒体技术大作业报告专 业:班 级:学 号:学生姓名:完成时间:目录说 明 ……………………………………………………3第一章概述 …………………………………………………4第二章技…

ES6入门之Generator函数

Generator Generator函数是ES6提供的一种异步编程解决方案,Generator函数是一个状态机,封装了多个内部状态。 执行Generator函数会返回一个遍历器对象,也就是说,Generator函数除了状态机,还是一个遍历器对象生成函数。…

reddit_Reddit如何设计和编码其详尽的愚人节体验,/ r / place

redditHere are three links worth your time:这是三个值得您花费时间的链接: How Reddit designed and coded its elaborate April Fool’s experience, /r/place (17 minute read) Reddit如何设计和编码其详尽的愚人节经验/ r / place( 阅读17分钟 ) These hacka…

CSS中属性的值和单位

CSS中值的单位 1.颜色值 被各种浏览器支持,并且作为 CSS 规范推荐的颜色名称只有 16 种,如下表所示。 百分比表示 color: rgb(100%, 100%, 100%); 这个声明将红、蓝、绿 3 种原色都设置为最大值,结果组合显示为白色。相反,可以设置…

mysql能否在手机端运行_在手机上安装linux并部署mysql,jupyter用于数据探索

因为现在有一台旧手机放在学校,之前使用的软路由内存只有128M,不方便存一些小的数据.手机的好处是可以一直开着,因此在手机上安装linux来替代树莓派做服务器是可行的(由于不需要对外,所以也不用购买服务器).安装linux首先安装busybox1.对于busybox,进入左上角settings,设置inst…

《走进SAP(第2版)》——2.8 SAP的目标是什么

本节书摘来自异步社区《走进SAP(第2版)》一书中的第2章,第2.8节,作者: 【德】Nancy Muir , Ian Kimbell , 等 更多章节内容可以访问云栖社区“异步社区”公众号查看。 2.8 SAP的目标是什么 走进SAP(第2版)…

尼康d850相机参数测试软件,尼康 - D850 - 产品介绍

类型数码单镜反光相机镜头卡口尼康F卡口(带有AF耦合和AF接点)有效视角尼康FX格式影像传感器格式FX格式影像传感器类型CMOS传感器有效像素数约4,575万影像传感器约35.9mm x 23.9mm总像素数约4,689万灰尘减少功能清洁影像传感器图像尺寸(像素)-FX (36x24) 影像区域(L) 8256 x 550…

我如何构建Kubernetes集群,以便我的同事可以更快地部署应用程序

by cheungpat通过cheungpat 我如何构建Kubernetes集群,以便我的同事可以更快地部署应用程序 (How I built a Kubernetes cluster so my coworkers could deploy apps faster) How do you encourage your development team to build more projects without being bo…

使用uWSGI部署django项目

先说说什么是uWSGI吧,他是实现了WSGI协议、uwsgi、http等协议的一个web服务器,那什么是WSGI呢? WSGI是一种Web服务器网关接口。它是一个Web服务器(如nginx)与应用服务器(如uWSGI服务器)通信的一…

8 包含min函数的栈

0 引言 题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min、push及pop的时间复杂度都是O(1). 1 抽象问题具体化 2 具体问题抽象分析 需要解决的两个主要问题如下。 &#x…

《Adobe Illustrator大师班:经典作品与完美技巧赏析》—Svetlana Makarova

本节书摘来自异步社区《Adobe Illustrator大师班:经典作品与完美技巧赏析》一书中的Svetlana Makarova,作者【英】Sharon Milne,更多章节内容可以访问云栖社区“异步社区”公众号查看。 Svetlana MakarovaAdobe Illustrator大师班:经典作品与…

navicat无法连接远程mysql数据库_navicat无法远程连接mysql的解决方法

近日在Ubuntu上安装了一个 MySQL 5.0,因为使用 phpMyAdmin 还必须安装 PHP,所以打算直接使用远程管理工具Navicat for MySQL 来连接。在 Ubuntu 中通过 mysql 命令行创建好一个数据表并分配了权限:代码如下:GRANT ALL ON testdb.* TO usera I…

有关软件测试的证书,软件测试证书有用吗

要想知道证书有什么用,我们就要详细了解软件评测师考试,以及拿到证书的价值。那么下面和小编来看看这篇软件测试证书有用吗,一定会有收获。一、证书考试软件评测师考试是全国计算机技术与软件技术资格考试的一个中级考试。考试不规定学历和资…

计算机科学导论第五版_五月份将开始提供438项免费在线编程和计算机科学课程

计算机科学导论第五版Five years ago, universities like MIT and Stanford first opened up free online courses to the public. Today, more than 700 schools around the world have created thousands of free online courses.五年前,麻省理工学院和斯坦福大学…

python D29 socketserver以及FTB

一、socketserver 基于tcp协议下的socket只能和一个客户端通信,如果用socketserver可以实现和多个客户端通信。 他是在socket的基础上进行封装,也就是说底层还是调用的socket,在py2.7里面叫做SocketServer也就是大写了两个S,在py3…

计算机节电模式不能打开,电脑进入节电模式打不开怎么办

大家好,我是时间财富网智能客服时间君,上述问题将由我为大家进行解答。电脑进入节电模式打不开的原因及解决方法如下:1、显示器和显卡接触不良解决办法:检查显示器和显卡的连接是否正确,接触是否良好;2、显…