工厂方法模式 | 学习笔记

简介: 快速学习工厂方法模式

开发者学堂课程【Scala 核心编程 - 进阶工厂方法模式学习笔记,与课程紧密连接,让用户快速学习知识。

课程地址https://developer.aliyun.com/learning/course/610/detail/9133


工厂方法模式


内容介绍:

一、学习设计模式的必要性

二、掌握设计模式的层次

三、设计模式介绍

四、设计模式的三种类型

五、简单工厂的基本介绍

六、传统方式的优缺点

七、使用简单工厂模式-进行改进

八、工厂方式模式

九、工厂方法模式应用案例


一、学习设计模式的必要性

1)面试会被问,所以必须学

2)读源码时看到别人在用,尤其是一些框架大量使用到设计模式,不学看不懂源码为什么这样写,比如 Runtime 的单例模式.

public class Runtime {

private static Runtime currentRuntime = new Runtime() ;

3)设计模式能让专业人之间交流方便

4)提高代码的易维护

5)设计模式是编程经验的总结,理解:即通用的编程应用场景的模式化,套路化(站在软件设计层面思考)。


二、掌握设计模式的层次

1)第1层:刚开始学编程不久,听说过什么是设计模式

2)第2层:有很长时间的编程经验,自己写了很多代码,其中用到了设计模式,但是自己却不知道

3)第3层:学习过了设计模式,发现自己已经在使用了,并且发现了一些新的模式挺好用的

4)第4层:阅读了很多别人写的源码和框架,在其中看到别人设计模式,并且能够领会设计模式的精妙和带来的好处。

5)第5层:代码写着写着,自己都没有意识到使用了设计模式,并且熟练的写了出来。


三、设计模式介绍

1)设计模式是程序员在面对同类软件工程设计问题所总结出来的有用的经验,模式【设计,思想】不是代码,而是某类问题的通用解决方案,设计模式(Design pattern)代表了最佳的实践。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

1.设计模式的本质提高软件的维护性,通用性和扩展性,并降低软件的复杂度【软件巨兽=》软件工程】。

2.<<设计模式>>是经典的书,作者是Erich Gamma、Richard Helm.Ralph Johnson和John Vlissides Design(俗称“四人组GOF”)

3.设计模式并不局限于某种语言,java,php,c++都有设计模式.


四、设计模式的三种类型

1)创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。

2)结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。

3)行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式( Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)、访问者模式。

注意:

不同的书籍上对分类和名称略有差别


五、简单工厂的基本介绍

1)简单工厂模式是属于创建型模式,但不属于23种GOF 设计模式之一。

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

1.简单工厂模式:

定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)

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

传统方法总是去这样调用

printIn("输入pizza的类型")

orderType= StdIn.readLine(

if (orderType equals("greek") {

this. pizza = new GreekPizza

} else if (orderType.equals("pepper')) {

this. pizza = new PepperPizza

} else {

break()

因为将来还会有销售,披萨,订购披萨,都要去写这段代码就会比较累,那就把这段代码抽象出来,抽象就是 Simple factory


六、传统方式的优缺点

1)优点是比较好理解,简单易操作。

2)缺点是违反了设计模式的 ocp 原则,即对扩展开放, 对修改关闭。即当给类增加新功能的时候,尽量不修改代码,或者尽可能少修改代码.

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


七、使用简单工厂模式-进行改进

简单工厂模式的设计方案:

定义一个实例化 Pizaa 对象的类,封装创建对象的代码。


八、工厂方式模式

看一个新的需求

披萨项目新的需求:客户在点披萨时,可以点不同口味的披萨,比如北京的奶酪pizza、北京的胡椒 pizza 或者是伦敦的奶酪 pizza、伦敦的胡椒 pizza.

思路1

使用简单工厂模式,创建不同的简单工厂类,比如BJPizzaSimpleFactory、LDPizzaSimpleFactory 等等.从当前这个案例来说,也是可以的,但是考虑到项目的规模,以及软件的可维护性、可扩展性考虑,它并不是特别好的方法

思路2

使用工厂方法模式,更强调的是把创建对象的行为下沉。

工厂方法模式设计方案:

将披萨项目的实例化功能抽象成抽象方法,在不同的口味点餐子类中具体实现。

工厂方法模式:

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


九、工厂方法模式应用案例

披萨项目新的需求:

客户在点披萨时,可以点不同口味的披萨,比如北京的奶酪pizza、北京的胡椒pizza或者是伦敦的奶酪pizza、伦敦的胡椒pizza

首先需要去扩展四个新的披萨,简单工厂模式和工厂方法模式并不冲突,将来一个项目里面可能多种方式共同使用,不是说用了工厂方法模式就不能再去用别的模式,创建四个新的pizza之后,把简单工厂模式拿掉,直接把创建行为下沉,北京奶酪披萨,北京胡椒pizza都继承披萨,工厂方法模式是把创建的行为分别对应到各自的子类中。

class BJCheesePizza extends Pizza { //

override def prepare(: Unit = {

this.name ="北京的奶酪pizza"

println(this.name + " preparing..")

}}

class BJPepperPizza extends Pizza {//

override def prepare(): Unit = {

this.name ="北京的胡椒pizza"

println(this.name + " preparing..")

}}

abstract class OrderPizza{//改写

breakable {

var orderType: String = null

var pizza: Pizza= null

do {

println(“请输入pizza的类型,使用工厂方法模式...")

orderType = Stdln.readLine()

//使用简单工厂模式来创建对象.

pizza = createPizza(orderType)

if (pizzanull) {

break()

}

pizza.prepare()

pizza.bake(

pizza.cut()

pizza.box()

} while (true)

}

//抽象方法

新建一个包(工厂方法模式)

def createPizza(t:String): Pizza

class BJOrderPizza extends OrderPizza {

override def createPizza(t: String): Pizza={

var pizza: Pizza= null

if (t.equals("cheese")) {

pizza = new BJCheesePizza

}else if (t.equals("pepper")) {

pizza = new BJPepperPizza

}

pizza

}}

Simple factory 就不要了,因为使用的是工厂方法模式,使用的是下沉,这时披萨扩充种类了,分别新建北京奶酪披萨和北京胡椒披萨,仍然让们继承披萨类,因为没有工厂,而且还要把它变成抽象的,因为现在有太多的籽类,所以需要把它变成抽象的

//抽象的方法,createpizza( orderType),让各个子类的实现order

def createPizza(t:String):

pizza(如果报错表示披萨的类型没有进行选择)pizza引一下工厂里面的pizza,现在订购的任务分而治之。

class BJOrderPizza extends orderPizza {

override def createPizza(t: string): Pizza = {

var pizza: Pizza = null

if (t.equals("cheese")) {

pizza = new BJCheesePizza

} else if (t. equals(" pepper")) {

pizza = new BJPepperpizza

}

pizza

}

代码运行如下:

//这里将orderPizza做成抽象

abstract class orderPizza {

var orderype : string =null

var pizza: pizza.Pizza =null(这里创建的时候pizza定义了两次,是会报错的,所以需要改为var pizza: pizza.,删掉一个pizza)

breakable {

do {

println("请输入pizza的类型使用工厂方法模式~~")

orderType = stdIn.readLine()

pizza= createPizza(orderType)

if (pizza == null)

break()

}

pizza.prepare()

pizza.bake()

pizza.cut()

pizza.box()

while (true)

}

相关文章
|
存储 分布式计算 并行计算
计算存储分离架构
计算存储分离架构
|
9月前
|
人工智能 移动开发 JavaScript
如何用uniapp打包桌面客户端exe包,vue或者uni项目如何打包桌面客户端之electron开发-优雅草央千澈以开源蜻蜓AI工具为例子演示完整教程-开源代码附上
如何用uniapp打包桌面客户端exe包,vue或者uni项目如何打包桌面客户端之electron开发-优雅草央千澈以开源蜻蜓AI工具为例子演示完整教程-开源代码附上
913 18
|
8月前
|
开发框架 安全 .NET
掌握 LINQ:通过示例解释 C# 中强大的 LINQ的集运算
通过本文的示例,我们详细介绍了C#中LINQ的强大集合运算功能。LINQ提供了一种简洁、灵活和类型安全的方式来查询和操作数据集合,从而大大提高了代码的可读性和可维护性。希望本文能帮助读者更好地掌握和应用LINQ,提高开发效率。
217 13
|
11月前
|
存储 Kubernetes Docker
使用 Docker 搭建碎片化知识卡片-Memos
Memos 是一个功能全面、易于使用的开源知识库和社交平台,适合个人和企业使用。它支持标签、过滤、搜索和多账户管理,提供多种隐私设置和后端存储选择,支持单点登录和 Docker 部署,注重数据的安全性和私密性。
357 12
使用 Docker 搭建碎片化知识卡片-Memos
|
Shell C语言 SoC
计基2—RISCV指令集介绍与汇编
计基2—RISCV指令集介绍与汇编
360 1
|
SQL 安全 测试技术
2021年职业院校技能大赛“网络安全”项目 江西省比赛任务书—B模块
B模块涵盖安全事件响应和网络数据取证,涉及多项应用安全挑战。任务包括使用nmap扫描靶机、弱口令登录、生成反弹木马、权限验证、系统内核版本检查、漏洞源码利用、文件名和内容提取等。此外,还有Linux渗透测试,要求访问特定目录下的文件并提取内容。应用服务漏洞扫描涉及服务版本探测、敏感文件发现、私钥解密、权限提升等。SQL注入测试需利用Nmap扫描端口,进行SQL注入并获取敏感信息。应急响应任务包括处理木马、删除恶意用户、修复启动项和清除服务器上的木马。流量分析涉及Wireshark数据包分析,查找黑客IP、枚举测试、服务破解等。渗透测试任务涵盖系统服务扫描、数据库管理、漏洞利用模块搜索等。
353 0
|
存储 分布式计算 Hadoop
Hadoop节点文件存储HBase设计目的
【6月更文挑战第2天】
148 6
|
机器学习/深度学习 编解码 人工智能
图像分割基础
图像分割基础
380 0
图像分割基础
|
机器学习/深度学习 传感器 算法
【语音加密】基于混沌logistic算法实现语音信号加密解密附GUI界面
【语音加密】基于混沌logistic算法实现语音信号加密解密附GUI界面
|
存储 JavaScript 前端开发