工厂模式-依赖倒置原则

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

 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,一经查实,立即删除!

相关文章

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

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

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

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

CSS中属性的值和单位

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

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

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

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大师班:经典作品与…

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

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

python D29 socketserver以及FTB

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

sphinx mysql存储引擎_基于Sphinx+MySQL的千万级数据全文检索(搜索引擎)架构设计...

Sphinx,单一索引最大可包含1亿条记录,在1千万条记录情况下的查询速度为0.x秒(毫秒级)。Sphinx创建索引的速度为:创建100万条记录的索引只需3~4分钟,创建1000万条记录的索引可以在50分钟内完成,而只包含最新…

4-1 线程安全性-原子性-atomic-1

转载于:https://www.cnblogs.com/ZHONGZHENHUA/p/10026627.html

delphi7 提示注册过期问题

很同情你得经过~ 因为我以前也是经常遇见这个问题~就和你说得一样~ 后来~ 我发现 下载使用的Delphi 7只能使用一个注册码,那就是:6AMD-PKG68E-DB8PP7-9SFE 3QH-9QW所以,你先把C:\Documents and Settings\Administrator\.borland文件夹下的两个文件删除然后用 Progra…

计算机开机引导的结果是,电脑开机显示引导媒体是怎么回事

电脑开机显示引导媒体是怎么回事分类:数据恢复常见问题|最后更新:2020年4月9日开机显示重新启动并选择适当的引导设备或插入1.如果主机上接有可移动存储介质(如光盘、移动硬盘、U盘等),将其拔掉,然后重启。2.如果仍然这样,进入主板设置中,依次检测以下几…

mysql怎样修改my ini_mysql修改my.ini报错怎么办

mysql修改my.ini报错的解决办法:首先将mysql默认编码改成utf8mb4,并修改【my.ini】配置;然后修改变量,并检查是否设置成功即可。更多相关免费学习推荐:mysql教程(视频)mysql修改my.ini报错的解决办法:将mys…

spring-DataSource

spring支持的dataSource有好多, 如:自带的org.springframework.jdbc.datasource.DriverManagerDataSource ibatis、c3p0、JDBC、hibernate等等; 首先看第一种,使用自带的datasource: 1、项目结构 提示:spri…

《Nmap渗透测试指南》—第7章7.8节后台打印机服务漏洞

本节书摘来自异步社区《Nmap渗透测试指南》一书中的第7章7.8节后台打印机服务漏洞,作者 商广明,更多章节内容可以访问云栖社区“异步社区”公众号查看。 7.8 后台打印机服务漏洞表7.8所示为本章节所需Nmap命令表,表中加粗命令为本小节所需命令——后台打…

VSCODE 配置远程调试环境

以下内容为本人的著作,如需要转载,请声明原文链接 微信公众号「englyf」https://mp.weixin.qq.com/s/f1KZOlL92ojes-r2l9rlCw 我的需求是,在Windows桌面环境下,通过 VSCODE 远程调试在服务器(或者其它远程主机)的工程代码。其实就…

html动态网页效果代码_教你制作网页的第一步

Internet中有许多漂亮、美观的网页,要制作出这样的网页,必须先了解什么是网页,网页的基本组成是怎样的。网页又称为Web页,一般都包含图像、文字和超链接等元素。按表现形式的不同,网页可分为静态网页和动态网页。静态网…

Spring Cloud 7:Gateway

Zuul 网关 Zuul 是 Netfilx 开源的一个 API Gateway 服务器,本质是一个 Web Servlet 应用。其在微服务架构体系中提供动态路由、监控、弹性、安全等边缘服务。 使用 Zuul 作为网关,其主要原因有以下几点: 1、Zuul、Ribbon 以及 Consul 客户端…

python基础-第三篇-函数编程

基本数据类型之set set是无序不允许重复的集合set创建:s set() 创建空集合 s {11,22,33}转换s set(可迭代数据)li [11,22,33,44] s set(li) print(s) #结果为{33, 11, 44, 22} 集合元素的添加与清空se {11,22,…

10个 Linux/Unix下 Bash 和 KSH shell 的作业控制实例

Linux 和 Unix 属于多任务的操作系统,也就是说一个系统在同一时间段内能运行多重任务(进程)。在这个新的博客系列,我将会列出相关的 Linux 和 Unix 作业(job)控制的命令,你可以通过这些命令在 Bash 或 Korn 还有 POSIX…