读 HeadFirst 设计模式
以往虽也看过相关设计模式的书籍,但能和与HeadFirt设计模式
这本书相比不是缺乏严谨性就是缺乏具体应用实例,还有幽默生动以及引人启发的观点。
设计原则
设计原则并不能光靠死记硬背,我们需要通过具体的设计模式来反思:该模式符合与违背了哪些设计原则。
不过在进入下文讨论之前,让我们先大概看看设计原则都有哪些。
- 封装变化
- 针对接口编程,而不是实现
- 多用组合少用继承
- 松耦合
- 对修改关闭,对扩展开放
- 依赖抽象不依赖具体
- 最少知识原则:只和亲密对象交谈
- 好莱坞原则:别打电话给我,我会打给你
- 单一职责
谈谈模板方法
我们都知道在GoF
里面的设计模式含有23种,在HeadFirst设计模式
一书中主要介绍了11种常见的设计模式。
本文挑选模板方法
这个设计模式着重介绍下,主要是该模式在前后端的开发中经常遇到,也便于理解。
为了探析模板方法
,让我们先看看日常生活中我们泡茶与泡咖啡的步骤。
泡茶
- 把水烧开
- 放茶包
- 往杯子中加水
- 加入柠檬
用Java实现如下:
public class Tea {
public void prepareRecipe() {
this.boilWater();
this.steepTeaBag();
this.pourInCup();
this.addLemon();
}
private void addLemon() {
System.out.println("add lemon...");
}
private void pourInCup() {
System.out.println("pour in cup...");
}
private void steepTeaBag() {
System.out.println("steep tea bag...");
}
private void boilWater() {
System.out.println("boil water...");
}
}
泡咖啡
- 把水烧开
- 研磨咖啡
- 往杯子中加水
- 加入糖和牛奶
用Java实现如下:
public class Coffee {
public void prepareRecipe() {
this.boilWater();
this.brewCoffeeGrinds();
this.pourInCup();
this.addSugarAndMilk();
}
private void addSugarAndMilk() {
System.out.println("add sugar and milk...");
}
private void pourInCup() {
System.out.println("pour in cup...");
}
private void brewCoffeeGrinds() {
System.out.println("brew coffee grinds...");
}
private void boilWater() {
System.out.println("boil Water....");
}
}
探析
当写完代码,不管你记不记得封装变化
这条设计原则,你肯定觉得泡茶喝泡咖啡有些地方代码非常的相似,例如:烧水
, 把水倒入被子
, 对于研磨咖啡豆
和放茶包
其本质都是:研磨喝的固体物质,我们可以把这些不变的部分提取出来。而把哪些变化的部分:添加糖和牛奶
和添加柠檬
封装起来。
我相信大多数人都会想到基础,构造一个饮料
基类。但是如何让设计更加灵活呢?
让我们一起来看看Java版的模板方法
实现:
public abstract class Beverage {
public void prepareRecipe() {
this.boilWater();
this.brew();
this.pourInCup();
if (customerWantsCondiments()) {
this.addCondiments();
}
}
public abstract void addCondiments();
public abstract void brew();
public void boilWater() {
System.out.println("boil water...");
}
public void pourInCup() {
System.out.println("pour in cup...");
}
public boolean customerWantsCondiments() {
return true;
}
}
在模板方法
中,我们定义了一系列的泡饮料的步骤,我们将变化的部分交给其子类去实现,可以说对变化进行了封装。而且在基类Beverage
中的customerWantsCondiments
方法就很巧妙,用户想不想加调料可以让他们自己决定。当然我们默认用户是想要加调料的。
我们再来看看两个实现类:Tea
和Coffee
。
public class Tea extends Beverage {
@Override
public void addCondiments() {
System.out.println("add lemon...");
}
@Override
public void brew() {
System.out.println("steep tea bag...");
}
}
public class Coffee extends Beverage {
@Override
public void addCondiments() {
System.out.println("add sugar and milk...");
}
@Override
public void brew() {
System.out.println("brew coffee grinds...");
}
}
这两个子类的实现都很简单,我们再来看看如何给出用户想不想在Coffee
中加入调料的选择条件。
public class CoffeeWithHook extends Beverage {
public void addCondiments() {
System.out.println("add sugar and milk...");
}
public void brew() {
System.out.println("brew coffee grinds...");
}
@Override
public boolean customerWantsCondiments() {
String answer = getUserInput();
if (answer.toLowerCase().startsWith("y")) {
return true;
} else {
return false;
}
}
private String getUserInput() {
String answer = null;
System.out.println("Would you like milk and sugar with your coffee (y/n) ?");
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
try {
answer = reader.readLine();
} catch (IOException e) {
System.out.println(e);
}
if (answer == null) {
return "no";
}
return answer;
}
}
是不是感觉很巧妙呢:D
总结模板方法
那么什么是模板方法
模式呢,其实我们只需记住两点就好了:
- 封装算法(也就是一些列步骤)
- 制造钩子
这时候我们再来看看Tempate Method
的定义:
模板方法模式在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
其实在我们的前端开发中,我们可以把Android、iOS开发等App的开发,Windows窗体,Unity游戏客户端,React等等GUI开发统称为前端开发
。我记得很多朋友喜欢叫啥前台
和后台
开发。。。我感觉不是很准确,首先后台
是什么?我们知道后台就是管理员操作的一个台子。私以为用来作为frontend
以及backend
的中文译语不是很准确也不专业的~
设计模式类目
总之,HeadFirst设计模式
强烈推荐给大家去看。不会错的,看的时候别忘了写实现,做笔记,思考。
这里在对设计模式做个大总结:
最后再把《HeadFirst》设计模式的开场图送给大家
读 HeadFirst 设计模式的更多相关文章
- 读headFirst设计模式 - 策略模式
有些人已经解决你的问题了 什么是设计模式?我们为什么要使用设计模式?怎样使用?按照书上的说法和我自己的理解,我认为是这样的:我们遇到的问题其他开发人员也遇到过,他们利用他们的智慧和经验将问题解决了,把 ...
- 读headFirst设计模式 - 装饰者模式
继承可以在复用父类代码的情况下扩展父类的功能,但同时继承增加了对象之间的耦合度,所以要慎用继承.那么有没有既能扩展父类的功能,又能使对象间解耦的方法呢?答案是肯定的,这就是我们今天要学习的装饰者模式. ...
- 读headFirst设计模式 - 工厂模式
每次写博客都不知道要怎么引入要写的主题,挺头疼的一件事.今天就直接开门见山,今天要学的就是工厂模式,工厂就是批量生产制造东西的地方.在这里,工厂就是批量生产对象的地方. 学习书上的例子 假如你现在有一 ...
- 读headFirst设计模式 - 观察者模式
上次学习了策略模式,这次来学习观察者模式.这次先把书上的例子学习一下,然后再自己写一个例子,看是否能做到举一反三(或者说触类旁通),不过要想真正的掌握还要多多思考和练习. 学习书上的例子 现在我们有一 ...
- 《HeadFirst设计模式》读后感——对学习设计模式的一些想法
最近看完了<HeadFirst设计模式>,GOF的<设计模式——可复用面向对象软件的基础>的创建型模式也读完了,经历了从一无所知到茅塞顿开再到充满迷惑的过程. 不得不说< ...
- 【Head-First设计模式】C#版-学习笔记-开篇及文章目录
原文地址:[Head-First设计模式]C#版-学习笔记-开篇及文章目录 最近一年断断续续的在看技术书,但是回想看的内容,就忘了书上讲的是什么东西了,为了记住那些看过的东西,最好的办法就是敲代码验证 ...
- Headfirst设计模式的C++实现——策略模式(Strategy)
前言 最近在学习<Headfirst设计模式>,里面的例子都是Java的.但是我对Java并不熟悉,所以试着用C++来实现书中的例子. 先来看看Duck以及子类 Duck.h #inclu ...
- HeadFirst设计模式读书笔记--目录
HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern) HeadFirst设计模式读书笔记(2)-观察者模式(Observer Pattern) HeadFirst设计 ...
- headfirst设计模式(2)—观察者模式
定义 观察者模式(有时又被称为发布(publish)-订阅(Subscribe)模式,在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知.这通常透过呼叫各观察 ...
随机推荐
- iOS安全攻防(二):后台daemon非法窃取用户iTunesstore信息
转自:http://blog.csdn.net/yiyaaixuexi/article/details/8293020 开机自启动 在iOS安全攻防(一):Hack必备的命令与工具中,介绍了如何编译自 ...
- Wireshark小技巧:将IP显示为域名
" 本文介绍如何使Wireshark报文窗口的Source栏及Destination内的IP直接显示为域名,提升报文分析效率." 之前内容发现部分不够严谨的地方,所以删除重发. ...
- UISlider增加触动区域
- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value { rect.origin. ...
- 无依赖单文件http-ftp文件服务器(py2)
网上看到的东东,居然在很合适堡垒机上传下载文件的场景. 这个只能在python2版本上跑, 我更改了自定义端口. 下次再改写个py3版本的. #!/usr/bin/env python "& ...
- 【洛谷P4589】[TJOI2018]智力竞赛(二分+最小链覆盖)
洛谷 题意: 给出一个\(DAG\),现在要选出\(n+1\)条可相交的链来覆盖,最终使得未被覆盖的点集中,权值最小的点的权值最大. 思路: 显然最终的答案具有单调性,故直接二分答案来判断: 直接将小 ...
- Jmeter之BeanShell
在Jmeter中各种分类组件中都有相应的BeanShell组件,这里简单的说明一下Beanshell的使用. 一.概念 BeanShell是一种符合Java语法的脚本语言,也有自己的一些特定语法 二. ...
- Pwn-Tell Me Something
题目地址 https://dn.jarvisoj.com/challengefiles/guestbook.d3d5869bd6fb04dd35b29c67426c0f05 先看看位数 64位ELF ...
- VMWare虚拟机提示:另一个程序已锁定文件的一部分,打不开磁盘...模块"Disk"启动失败的解决办法
重启了电脑之后,打开VMware就发现出现了“锁定文件失败,打不开磁盘......模块"Disk"启动失败.”这些文字 为什么会出现这种问题: 这是因为虚拟机在运行的时候,会锁定文 ...
- Python网络编程基础 ❶ 计算机网络基础 初用socket模块
1.计算机网络基础 C/S 客户端/服务器端 B/S 浏览器端/服务器端 mac地址,ip地址,子网掩码,与计算得到网段,端口号每台计算机的网卡都有全球唯一的地址,在生产时已经写进去了. ip地址 ...
- 为什么用时序电路实现CPU
时序电路 我们带着如下疑问来看时序电路: 1.为什么CPU要用时序电路,时序电路与普通逻辑电路有什么区别. 2.触发器.锁存器以及时钟脉冲对时序电路的作用是什么,它们是如何工作的. 带着这两个问题,我 ...