软件构造第11次课复习——工厂模式
临近考试,我温习了一下软件构造的第十一章,有了一些感悟,发一篇博客以抛砖引玉,如有错误请在评论区中指出,谢谢各位。
设计模式分为三种——创造型,结构型,行为类(Creational patterns,Structural patterns,Structural patterns)其中创造型“关注对象创建的过程”,典型代表是工厂方法模式。本文主要介绍工厂方法模式。
要用一句话来介绍工厂方法模式的话,就是“不用构造器产生新对象,而用‘工厂方法’产生新对象”。什么是工厂方法呢?(简单)工厂方法就是形如这样的方法
他的使用是这样的 Trace log = new Factory().getTrace("system");
那这时候你可能有疑问:这和直接调用FileTrace有什么区别?这不就是脱裤子放屁——多此一举吗?请听我慢慢说来:
假设现在需要有一个打印错误消息的接口Trace,这个接口目前需要从文件中读取错误信息并打印,和从系统中读取信息并打印,但是这个接口以后需要从别的地方读取信息并打印(比如说,从内存中读取信息,只是举个例子),所以需要这个接口有很好的可拓展性,那么你作为程序设计者,要如何实现这个接口呢?(假定这个接口需要实现三个函数:
1. public void setDebug( boolean debug );
2. public void debug( String message );
3. public void error( String message );
每个类的这三个函数实现都不同
)
方案一:
public interface Trace {
public void setDebug( boolean debug );
public void debug( String message );
public void error( String message );
}
public class SystemTrace implements Trace
{ private boolean debug;
public void setDebug( boolean debug )
{ …}
public void debug( String message )
{ … }
public void error( String message )
{… }
}
public class FileTrace implements Trace
{ private boolean debug;
public void setDebug( boolean debug )
{ …}
public void debug( String message )
{ … }
public void error( String message )
{… }
}
用户想用什么就自己调用 比如FileTrace a=new FileTrace();
这样做有几个问题:1.把内部代码的类的名字泄露给用户了。
1.用户需要知道代码类名才能创建对象。这里你可能又有疑问:用户要调用代码不就是要知道类名才知道自己要调什么吗?不知道类名怎么知道要调什么?何况让他知道又有什么问题?
假如你雇用的3000一个月的程序员因为工资太少,女朋友和他分手了,喝了三两白的。
醉醺醺的他坐到工位下写下了以下的代码
public class MenoryTraces implements Trace
{
…
}
来实现在内存中读错误信息,乍一看好像没什么问题,静态检查也没有bug,但是用户调用以下函数的时候会出错:
MenoryTrace a=new MenoryTrace();
仔细一看才发现,源代码的MenoryTrace多了一个s,变成MenoryTraces!
倘若是一个大项目,这种复查是很花时间的,这就是不隐藏内部实现的恶果。
即使不考虑这种偶然情况,假若有一天因为需要打印多条错误信息,程序员把FileTrace,SystemTrace全在后面加s,那么以前的代码不就遭殃了吗?所以要尽量做到源代码和用户的“解耦”。
如果使用简单工厂方法
用户在调用的时候只需要输入参数,就可以返回正确的类型,不用管trace后面加不加s的问题了。客户端也可以免去直接new的职责。
但是这样的话所有的new都在这个模式里完成了,一旦这个程序里有bug,所有的trace类都会遭殃,导致了添加代码的艰难和代码的不安全,那么就有了第二种模式
另外一种模式,工厂方法模式(注意,在老师的ppt中,把前面的简单工厂方法模式也化作工厂方法模式)
interface TraceFactory {
Trace getTrace();
void otherOperation();
}
public class SystemTraceFactory implements TraceFactory
{ public Trace getTrace()
{ … //other operations return new SystemTrace(); }
}
public class FileTraceFactory implements TraceFactory
{ public Trace getTrace()
{ return new FileTrace();
}
}
这样的
用户调用的时候是这样调用的
Trace log1 = new SystemTraceFactory().getTrace();
这种方法的好处是可以在工厂模式中实现别的方法,而且把FileTrace和SystemTrace隐藏起来了,假如新建类名特别长,像FindBugsInSystemAndGetTraceFromSystem用户不需要去记忆这么长且复杂的名字。但是用户仍需要判断自己调用的方法的工厂名字,所以说不同的工厂方法实现也有好有坏。
下面简要介绍一下静态工厂方法,静态工厂方法曾经在19年考题中出现过。它的实现类似于这种:
public class SystemTraceFactory
{ public static Trace getTrace()
{ return new SystemTrace(); }
}
或是这种:
public class TraceFactory
{ public static Trace getTrace(String type)
{ if(type.equals("file") return new FileTrace();
else if (type.equals("system")
return new SystemTrace(); }
}
简单来说就是在方法的前面加上static,这样做有什么好处呢?
相比于通过构造器构造对象,其可以1.可具有指定的更有意义的名称,不必和类名一致
2. 不必在每次调用的时候都创建新的工厂对象
3. 可以返回原返回类型的任意子类型(SystemTrace或FileTrace)
软件构造第11次课复习——工厂模式相关推荐
- 工厂三兄弟之简单工厂模式
本文转载自 :http://blog.csdn.net/lovelion/article/details/9300337 工厂模式是最常用的一类创建型设计模式,通常我们所说的工厂模式是指工厂方法模式, ...
- java之设计模式工厂三兄弟之简单工厂模式
[学习难度:★★☆☆☆,使用频率:★★★☆☆] 工厂模式是最常用的一类创建型设计模式,通常我们所说的工厂模式是指工厂方法模式,它也是使用频率最高的工厂模式.本章将要学习的简单工厂模式是工厂方法模式的& ...
- 【设计模式】2.工厂模式
文章目录 1. 工厂模式概述 2. 简单工厂模式 3. 工厂方法模式 4. 抽象工厂模式 1. 工厂模式概述 工厂模式属于创建型模式的一种. 在java中,万物皆对象,这些对象都需要创建,如果创建的时 ...
- java设计模式之工厂模式(UML类图分析+代码详解)
大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设 ...
- java 三种工厂模式(简单工厂+工厂方法+抽象工厂)
一.简单工厂模式 概述 简单工厂模式:定义一个工厂类,它可以根据参数的不同返回不同类的 实例,被创建的实例通常都具有共同的父类.因为在简单工厂模式中用于创建实例的方法是静态(static)方法,因 ...
- java中的工厂_java中的工厂模式
1.工厂模式 java中的工厂模式,个人理解是:要想制作一个汽车,则必须有轮子,发动机,座椅等. 1.创建一个接口,并且使得轮子,发动机,座椅三个实现类实现这个接口. 2.创建一个工厂,生成基于给定信 ...
- 2022 - 软件构造复习
软件生命周期 一个软件产品或软件系统经历孕育.诞生.成长.成熟.衰亡等阶段,一般称为软件生存周期(软件生命周期). 根据软件所处的状态和特征,划分软件生存周期. 需求定义.软件设计.软件实现.软件维护 ...
- 2022哈工大软件构造课程总结与经验分享(复习指导)
一.软构1-3讲 1.软件构造的多维度视图和质量目标 2.软件测试与测试优先的编程 3.软件构造过程与配置管理 二.软构4-8讲 4.数据类型与类型检验 5.设计规约 6.抽象数据类型 (ADT) 7 ...
- 2021哈工大软件构造期末考点复习笔记
第一节 多维视图和质量目标 软件构造多维度视图 红色标注为重点(考试会考选择题) Moment 特定时刻的软件形态 Period 软件形态随时间的变化 AST (Abstract Syntax Tre ...
最新文章
- Docker(十三):Docker 清理命令集锦
- 不要错过!MICCAI 2019 所有论文完整下载
- jquery 手型 鼠标穿过时_三模无线搭配对称手型设计,游戏致胜利器,ROG烈刃2无线鼠标...
- CSS工具之CSS重置(CSS Reset)
- Vue.js(2.x)之插值
- 使用 JavaScript 下载文件
- 【SSM分布式架构电商项目-32】Dubbo入门
- C#winform之自定义按钮形状
- 决策树_Python3实现代码及注释
- C#开发工控上位机编程 csdn_5种将死的编程语言
- c语言 程序数据要五行输出,C语言编程入门之--第三章编写第一个C语言程序
- CH340G,CH340C,CH340E,CH340T,CH341T等芯片后缀的意思详解
- 使用 Swift 在 iOS 10 中集成 Siri —— SiriKit 教程(Part 1) 1
- Linux 命令 技能
- Linux之Xinetd服务介绍
- OpenAI 推出漏洞赏金计划,最高奖励 2 万美元;京东零售开启 5 年来最大组织变革;​Django 4.2|极客头条
- cad 打开硬件加速卡_CAD经常性卡顿?要怎么解决?
- 【Matlab中diag函数的用法】
- 深度 | 白帽汇赵武:以安徒生之名打造企业威胁感知神器
- python x y 下载_Python(x,y)的下载安装
热门文章
- GAMES101笔记_Lec07~09_着色 Shading
- LPF与HPF是什么意思?
- 使用 HTML CSS 和 JavaScript 创建星级评分系统
- JavaScript中的scrollTop(js中的scrollTop,滚动到顶部,javascript滚动到顶部)
- 十大高颜值蓝牙耳机排行榜,最受欢迎的真无线蓝牙耳机前十名
- matlab亥姆霍兹线圈叠加原理,亥姆霍兹线圈仿真剖析.docx
- 个人英文小词典--抽取英文阅读重要的名词、动词、形容词、副词并输出其翻译结果
- Java爬取王者荣耀全英雄全皮肤图片
- Directx11教程(66) D3D11屏幕文本输出(1)
- 2020互联网大厂的薪资职级一览