
设计模式
文章平均质量分 69
weixin_46722612
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
行为型模式——访问者
访问者模式(Visitor)是一种操作一组对象的操作,它的目的是不改变对象的定义,但允许新增不同的访问者,来定义新的操作。访问者模式的设计比较复杂,如果我们查看GoF原始的访问者模式,它是这么设计的:上述模式的复杂之处在于上述访问者模式为了实现所谓的“双重分派”,设计了一个回调再回调的机制。因为Java只支持基于多态的单分派模式,这里强行模拟出“双重分派”反而加大了代码的复杂性。这里我们只介绍简化的访问者模式。假设我们要递归遍历某个文件夹的所有子文件夹和文件,然后找出.java文件,正常的做法是写.原创 2021-03-26 00:04:34 · 83 阅读 · 0 评论 -
行为型模式——模板方法
模板方法(Template Method)是一个比较简单的模式。它的主要思想是,定义一个操作的一系列步骤,对于某些暂时确定不下来的步骤,就留给子类去实现好了,这样不同的子类就可以定义出不同的步骤。因此,模板方法的核心在于定义一个“骨架”。我们还是举例说明。假设我们开发了一个从数据库读取设置的类:public class Setting { public final String getSetting(String key) { String value = readFromD.原创 2021-03-25 08:45:47 · 103 阅读 · 0 评论 -
行为型模式——策略
策略模式:Strategy,是指,定义一组算法,并把其封装到一个对象中。然后在运行时,可以灵活的使用其中的一个算法。策略模式在Java标准库中应用非常广泛,我们以排序为例,看看如何通过Arrays.sort()实现忽略大小写排序:import java.util.Arrays;public class Main { public static void main(String[] args) throws InterruptedException { String[] ar.原创 2021-03-25 08:45:18 · 107 阅读 · 0 评论 -
行为型模式——状态
什么是状态?我们以QQ聊天为例,一个用户的QQ有几种状态:离线状态(尚未登录);正在登录状态;在线状态;忙状态(暂时离开)。如何表示状态?我们定义一个enum就可以表示不同的状态。但不同的状态需要对应不同的行为,比如收到消息时:if (state == ONLINE) { // 闪烁图标} else if (state == BUSY) { reply("现在忙,稍后回复");} else if ...状态模式的目的是为了把上述一大串if…else…的逻辑给分拆到不.原创 2021-03-25 08:44:49 · 105 阅读 · 0 评论 -
行为型模式——观察者
观察者模式(Observer)又称发布-订阅模式(Publish-Subscribe:Pub/Sub)。它是一种通知机制,让发送通知的一方(被观察方)和接收通知的一方(观察者)能彼此分离,互不影响。要理解观察者模式,我们还是看例子。假设一个电商网站,有多种Product(商品),同时,Customer(消费者)和Admin(管理员)对商品上架、价格改变都感兴趣,希望能第一时间获得通知。于是,Store(商场)可以这么写:public class Store { Customer custom.原创 2021-03-25 08:44:28 · 89 阅读 · 0 评论 -
行为型模式——备忘录
备忘录模式(Memento),主要用于捕获一个对象的内部状态,以便在将来的某个时候恢复此状态。其实我们使用的几乎所有软件都用到了备忘录模式。最简单的备忘录模式就是保存到文件,打开文件。对于文本编辑器来说,保存就是把TextEditor类的字符串存储到文件,打开就是恢复TextEditor类的状态。对于图像编辑器来说,原理是一样的,只是保存和恢复的数据格式比较复杂而已。Java的序列化也可以看作是备忘录模式。在使用文本编辑器的时候,我们还经常使用Undo、Redo这些功能。这些其实也可以用备忘录模式实现.原创 2021-03-25 08:44:02 · 101 阅读 · 0 评论 -
行为型模式——中介
中介模式(Mediator)又称调停者模式,它的目的是把多方会谈变成双方会谈,从而实现多方的松耦合。有些童鞋听到中介立刻想到房产中介,立刻气不打一处来。这个中介模式与房产中介还真有点像,所以消消气,先看例子。考虑一个简单的点餐输入:这个小系统有4个参与对象:多选框;“选择全部”按钮;“取消所有”按钮;“反选”按钮。它的复杂性在于,当多选框变化时,它会影响“选择全部”和“取消所有”按钮的状态(是否可点击),当用户点击某个按钮时,例如“反选”,除了会影响多选框的状态,它又可能影响“选择全.原创 2021-03-25 08:43:34 · 68 阅读 · 0 评论 -
行为型模式——解释器
解释器模式(Interpreter)是一种针对特定问题设计的一种解决方案。例如,匹配字符串的时候,由于匹配条件非常灵活,使得通过代码来实现非常不灵活。举个例子,针对以下的匹配条件:以+开头的数字表示的区号和电话号码,如+861012345678;以英文开头,后接英文和数字,并以.分隔的域名,如www.liaoxuefeng.com;以/开头的文件路径,如/path/to/file.txt;…因此,需要一种通用的表示方法——正则表达式来进行匹配。正则表达式就是一个字符串,但要把正则表达式解析为.原创 2021-03-25 08:42:37 · 127 阅读 · 0 评论 -
行为型模式——迭代器
迭代器模式(Iterator)实际上在Java的集合类中已经广泛使用了。我们以List为例,要遍历ArrayList,即使我们知道它的内部存储了一个Object[]数组,也不应该直接使用数组索引去遍历,因为这样需要了解集合内部的存储结构。如果使用Iterator遍历,那么,ArrayList和LinkedList都可以以一种统一的接口来遍历:List<String> list = ...for (Iterator<String> it = list.iterator(); it.原创 2021-03-25 08:43:11 · 70 阅读 · 0 评论 -
行为型模式——命令
命令模式(Command)是指,把请求封装成一个命令,然后执行该命令。在使用命令模式前,我们先以一个编辑器为例子,看看如何实现简单的编辑操作:public class TextEditor { private StringBuilder buffer = new StringBuilder(); public void copy() { ... } public void paste() { String text = getFrom.原创 2021-03-25 08:41:49 · 118 阅读 · 0 评论 -
行为型模式——责任链
责任链模式(Chain of Responsibility)是一种处理请求的模式,它让多个处理器都有机会处理该请求,直到其中某个处理成功为止。责任链模式把多个处理器串成链,然后让请求在链上传递:在实际场景中,财务审批就是一个责任链模式。假设某个员工需要报销一笔费用,审核者可以分为:Manager:只能审核1000元以下的报销;Director:只能审核10000元以下的报销;CEO:可以审核任意额度。用责任链模式设计此报销流程时,每个审核者只关心自己责任范围内的请求,并且处理它。对于超出自.原创 2021-03-23 11:06:55 · 75 阅读 · 0 评论 -
结构型模式——代理
代理模式,即Proxy,它和Adapter模式很类似。我们先回顾Adapter模式,它用于把A接口转换为B接口:public BAdapter implements B { private A a; public BAdapter(A a) { this.a = a; } public void b() { a.a(); }}而Proxy模式不是把A接口转换成B接口,它还是转换成A接口:public AProxy imple.原创 2021-03-23 10:49:05 · 74 阅读 · 0 评论 -
结构型模式——享元
享元(Flyweight)的核心思想很简单:如果一个对象实例一经创建就不可变,那么反复创建相同的实例就没有必要,直接向调用方返回一个共享的实例就行,这样即节省内存,又可以减少创建对象的过程,提高运行速度。享元模式在Java标准库中有很多应用。我们知道,包装类型如Byte、Integer都是不变类,因此,反复创建同一个值相同的包装类型是没有必要的。以Integer为例,如果我们通过Integer.valueOf()这个静态工厂方法创建Integer实例,当传入的int范围在-128~+127之间时,会直接.原创 2021-03-23 09:50:35 · 86 阅读 · 0 评论 -
结构型模式——外观
外观模式,即Facade,是一个比较简单的模式。它的基本思想如下:如果客户端要跟许多子系统打交道,那么客户端需要了解各个子系统的接口,比较麻烦。如果有一个统一的“中介”,让客户端只跟中介打交道,中介再去跟各个子系统打交道,对客户端来说就比较简单。所以Facade就相当于搞了一个中介。我们以注册公司为例,假设注册公司需要三步:向工商局申请公司营业执照;在银行开设账户;在税务局开设纳税号。以下是三个系统的接口:// 工商注册:public class AdminOfIndustry {原创 2021-03-23 09:37:49 · 217 阅读 · 0 评论 -
结构型模式——装饰器
装饰器(Decorator)模式,是一种在运行期动态给某个对象的实例增加功能的方法。我们在IO的Filter模式一节中其实已经讲过装饰器模式了。在Java标准库中,InputStream是抽象类,FileInputStream、ServletInputStream、Socket.getInputStream()这些InputStream都是最终数据源。现在,如果要给不同的最终数据源增加缓冲功能、计算签名功能、加密解密功能,那么,3个最终数据源、3种功能一共需要9个子类。如果继续增加最终数据源,或者增加.原创 2021-03-23 09:05:33 · 106 阅读 · 0 评论 -
结构型模式——组合
组合模式(Composite)经常用于树形结构,为了简化代码,使用Composite可以把一个叶子节点与一个父节点统一起来处理。我们来看一个具体的例子。在XML或HTML中,从根节点开始,每个节点都可能包含任意个其他节点,这些层层嵌套的节点就构成了一颗树。要以树的结构表示XML,我们可以先抽象出节点类型Node:public interface Node { // 添加一个节点为子节点: Node add(Node node); // 获取子节点: List<N.原创 2021-03-23 08:33:24 · 88 阅读 · 0 评论 -
结构型模式——桥接
桥接模式的定义非常玄乎,直接理解不太容易,所以我们还是举例子。假设某个汽车厂商生产三种品牌的汽车:Big、Tiny和Boss,每种品牌又可以选择燃油、纯电和混合动力。如果用传统的继承来表示各个最终车型,一共有3个抽象类加9个最终子类:如果要新增一个品牌,或者加一个新的引擎(比如核动力),那么子类的数量增长更快。所以,桥接模式就是为了避免直接继承带来的子类爆炸。我们来看看桥接模式如何解决上述问题。在桥接模式中,首先把Car按品牌进行子类化,但是,每个品牌选择什么发动机,不再使用子类扩充,而是通过.原创 2021-03-23 08:33:08 · 104 阅读 · 0 评论 -
结构型模式——适配器
适配器模式是Adapter,也称Wrapper,是指如果一个接口需要B接口,但是待传入的对象却是A接口,怎么办?我们举个例子。如果去美国,我们随身带的电器是无法直接使用的,因为美国的插座标准和中国不同,所以,我们需要一个适配器。在程序设计中,适配器也是类似的。我们已经有一个Task类,实现了Callable接口:public class Task implements Callable<Long> { private long num; public Task(long .原创 2021-03-23 08:32:55 · 120 阅读 · 0 评论 -
创建型模式——单例
单例模式(Singleton)的目的是为了保证在一个进程中,某个类有且仅有一个实例。因为这个类只有一个实例,因此,自然不能让调用方使用new Xyz()来创建实例了。所以,单例的构造方法必须是private,这样就防止了调用方自己创建实例,但是在类的内部,是可以用一个静态字段来引用唯一创建的实例的:public class Singleton { // 静态字段引用唯一实例: private static final Singleton INSTANCE = new Singleton.原创 2021-03-23 08:32:39 · 78 阅读 · 0 评论 -
创建型模式——原型
原型模式,即Prototype,是指创建新对象的时候,根据现有的一个原型来创建。我们举个例子:如果我们已经有了一个String[]数组,想再创建一个一模一样的String[]数组,怎么写?实际上创建过程很简单,就是把现有数组的元素复制到新数组。如果我们把这个创建过程封装一下,就成了原型模式。用代码实现如下:// 原型:String[] original = { "Apple", "Pear", "Banana" };// 新对象:String[] copy = Arrays.copyOf(or.原创 2021-03-23 08:32:27 · 104 阅读 · 0 评论 -
创建型模式——抽象工厂
抽象工厂模式(Abstract Factory)是一个比较复杂的创建型模式。抽象工厂模式和工厂方法不太一样,它要解决的问题比较复杂,不但工厂是抽象的,产品是抽象的,而且有多个产品需要创建,因此,这个抽象工厂会对应到多个实际工厂,每个实际工厂负责创建多个实际产品:这种模式有点类似于多个供应商负责提供一系列类型的产品。我们举个例子:假设我们希望为用户提供一个Markdown文本转换为HTML和Word的服务,它的接口定义如下:public interface AbstractFactory { .原创 2021-03-22 19:41:32 · 79 阅读 · 0 评论 -
创建型模式——生成器
生成器模式(Builder)是使用多个“小型”工厂来最终创建出一个完整对象。当我们使用Builder的时候,一般来说,是因为创建这个对象的步骤比较多,每个步骤都需要一个零部件,最终组合成一个完整的对象。我们仍然以Markdown转HTML为例,因为直接编写一个完整的转换器比较困难,但如果针对类似下面的一行文本:# this is a heading转换成HTML就很简单:<h1>this is a heading</h1>因此,我们把Markdown转HTML看作一.原创 2021-03-22 19:27:00 · 78 阅读 · 0 评论 -
JAVA笔记——设计模式
设计模式,即Design Patterns,是指在软件设计中,被反复使用的一种代码设计经验。使用设计模式的目的是为了可重用代码,提高代码的可扩展性和可维护性。为什么要使用设计模式?根本原因还是软件开发要实现可维护、可扩展,就必须尽量复用代码,并且降低代码的耦合度。设计模式主要是基于OOP编程提炼的,它基于以下几个原则:开闭原则由Bertrand Meyer提出的开闭原则(Open Closed Principle)是指,软件应该对扩展开放,而对修改关闭。这里的意思是在增加新功能的时候,能不改代码就尽量原创 2021-03-22 14:32:23 · 77 阅读 · 0 评论 -
创建型模式——工厂方法
工厂方法即Factory Method,是一种对象创建型模式。工厂方法的目的是使得创建对象和使用对象是分离的,并且客户端总是引用抽象工厂和抽象产品:我们以具体的例子来说:假设我们希望实现一个解析字符串到Number的Factory,可以定义如下:public interface NumberFactory { Number parse(String s);}有了工厂接口,再编写一个工厂的实现类:public class NumberFactoryImpl implements Nu.原创 2021-03-22 14:31:59 · 96 阅读 · 0 评论