以往虽也看过相关设计模式的书籍,但能和与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方法就很巧妙,用户想不想加调料可以让他们自己决定。当然我们默认用户是想要加调料的。

我们再来看看两个实现类:TeaCoffee

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 设计模式的更多相关文章

  1. 读headFirst设计模式 - 策略模式

    有些人已经解决你的问题了 什么是设计模式?我们为什么要使用设计模式?怎样使用?按照书上的说法和我自己的理解,我认为是这样的:我们遇到的问题其他开发人员也遇到过,他们利用他们的智慧和经验将问题解决了,把 ...

  2. 读headFirst设计模式 - 装饰者模式

    继承可以在复用父类代码的情况下扩展父类的功能,但同时继承增加了对象之间的耦合度,所以要慎用继承.那么有没有既能扩展父类的功能,又能使对象间解耦的方法呢?答案是肯定的,这就是我们今天要学习的装饰者模式. ...

  3. 读headFirst设计模式 - 工厂模式

    每次写博客都不知道要怎么引入要写的主题,挺头疼的一件事.今天就直接开门见山,今天要学的就是工厂模式,工厂就是批量生产制造东西的地方.在这里,工厂就是批量生产对象的地方. 学习书上的例子 假如你现在有一 ...

  4. 读headFirst设计模式 - 观察者模式

    上次学习了策略模式,这次来学习观察者模式.这次先把书上的例子学习一下,然后再自己写一个例子,看是否能做到举一反三(或者说触类旁通),不过要想真正的掌握还要多多思考和练习. 学习书上的例子 现在我们有一 ...

  5. 《HeadFirst设计模式》读后感——对学习设计模式的一些想法

    最近看完了<HeadFirst设计模式>,GOF的<设计模式——可复用面向对象软件的基础>的创建型模式也读完了,经历了从一无所知到茅塞顿开再到充满迷惑的过程. 不得不说< ...

  6. 【Head-First设计模式】C#版-学习笔记-开篇及文章目录

    原文地址:[Head-First设计模式]C#版-学习笔记-开篇及文章目录 最近一年断断续续的在看技术书,但是回想看的内容,就忘了书上讲的是什么东西了,为了记住那些看过的东西,最好的办法就是敲代码验证 ...

  7. Headfirst设计模式的C++实现——策略模式(Strategy)

    前言 最近在学习<Headfirst设计模式>,里面的例子都是Java的.但是我对Java并不熟悉,所以试着用C++来实现书中的例子. 先来看看Duck以及子类 Duck.h #inclu ...

  8. HeadFirst设计模式读书笔记--目录

    HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern) HeadFirst设计模式读书笔记(2)-观察者模式(Observer Pattern) HeadFirst设计 ...

  9. headfirst设计模式(2)—观察者模式

    定义 观察者模式(有时又被称为发布(publish)-订阅(Subscribe)模式,在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知.这通常透过呼叫各观察 ...

随机推荐

  1. shell下判断文件夹或文件是否存在

    文件夹不存在则创建 if [ ! -d "/data/" ];then mkdir /data else echo "文件夹已经存在" fi 文件存在则删除 i ...

  2. v8js-在PHP中运行javascript代码

    起因之前写自动登录操作一个网站的PHP脚本,但是发现该网站用js代码做了cookie的计算和验证,所以使用了v8js. 安装安装v8.(Mac:brew install v8)使用pecl insta ...

  3. sql使用cte表达式进行递归查询

    --递归获取所有子节点 with temp as ( select * from MK_Base_Department where F_DepartmentId='5f258320-c1b7-42a4 ...

  4. mysql简单的sql操作语句

    一,常用.简单的SQL操作语句 1.数据库操作: 1)创建数据库: create database database_name: 创建并设置字符编码 create database database_ ...

  5. 【CobaltStrike】对CobaltStrike内置功能模块的了解

    对CobaltStrike内置功能模块的了解 0x00 右键功能列表 Interact 打开beacon Access dump hashes 获取hash Elevate 提权 Golden Tic ...

  6. axios+vue实现动态渲染员工数据+数据是对象

    <style> table{ width: 600px; margin: 0 auto; text-align: center; border-collapse: collapse; /* ...

  7. 初学JavaScript正则表达式(二)

    正则表达式的实例化与标识符 字面量: var reg = /\bis\b/g // \b--字符边界 g全文搜索 查找单词为is的字符 He is a boy. IS He? 构造函数: var re ...

  8. URL、URI、URN之间的区别

    URL统一资源定位符 URI统一资源标识符 URN统一资源名称 URL是URI的一个特例. URI由URL和URN两部分组成. 在java类中,URI类不包含任何访问资源的方法,它唯一的作用就是解析. ...

  9. Unity 2018 Cookbook (Matt Smith 著)

    1. Displaying Data with Core UI Elements (已看) 2. Responding to User Events for Interactive UIs (已看) ...

  10. 【Java并发专题之三】Java线程互斥、协作原理

    (I)Java线程互斥原理之synchronized原理 从JDK5引入CAS原子操作,但没有对synchronized关键字做优化,而是增加了J.U.C.concurrent,concurrent包 ...