设计模式
随着对设计模式的学习,应该总结出一系列文章以供日后复习,顺便能够为想要学习相关知识的朋友提供一些资料
一个偏执狂
这个作者很懒,什么都没留下…
展开
-
与设计模式相处
模式是在某情境下,针对某问题的某种解决方案。 模式必须应用于一个重复出现的问题。 模式分类: 何时使用模式?当你在设计的时候,如果确定在你的设计中可以利用某个模式解决某个问题,那么就使用这个模式!如果有更简单的解决方案,那么在决定使用模式之前应该先考虑这个方案。 并非只有在设计时才考虑引进模式,在重构时也要这样做! 反模式告诉你如何采用一个不好的解决方案解决一个问题。 让设计模式自然而...原创 2019-03-29 09:41:49 · 298 阅读 · 0 评论 -
其他模式
桥接模式(Bridge Pattern) 使用桥接模式可以同时改变实现及抽象,而不会互相影响 生成器模式(Builder Pattern) 生成器模式封装一个产品的构造过程,并允许按步骤构造。与工厂模式有本质不同。 责任链模式(Chain of Responsibility Pattern) 责任链模式可以让一个以上的对象有机会处理某个请求。比如拦截器链就是责任链模式的最佳实现。 蝇量...原创 2019-03-29 09:41:43 · 511 阅读 · 0 评论 -
复合模式
GitHub代码 复合模式(Compound Pattern)就是一种由模式所构成的模式。最典型的例子就是MVC(Model-View-Controller)。 控制器把控制逻辑从视图中分离,让模型和视图之间解耦。通过保持控制器和视图之间松耦合,设计就更有弹性而且容易扩展,足以容纳以后的改变。 在Web开发中,大家非常熟悉的MVC变型被称为“Model 2”,其使用了Servlet和JSP技...原创 2019-03-29 09:41:37 · 543 阅读 · 0 评论 -
代理模式
GitHub代码 远程代理 场景描述:我们想要一台远程监视器! 我们可能需要引入一点新概念了,比如远程代理。 远程代理就好比“远程对象的本地代表”。何谓有“远程对象”?这是一种对象,活在不同的Java虚拟机(JVM)堆中(更一般的说法为,在不同的地址空间运行的远程对象)。何谓“本地代表”?这是一种可以由本地方法调用的对象,其行为会转发到远程对象中。 客户对象所做的就像是在做远程方法的调用,但其实只...原创 2019-03-29 09:41:26 · 274 阅读 · 0 评论 -
状态模式
GitHub代码 场景描述:我们想要写一个糖果机,如下是它的状态图。 我们想到最直接的解决办法就是,大段的if else块 但是正如我们之前所说,if else块一旦遇到需求变更等情况,不仅面临着大量代码的重写等,还面临着出现bug的情况。并且这种设计不符合我们之前提到的开放-关闭设计原则(对扩展开放,对修改关闭)。 比如我们突然要加一条随机幸运儿,有10%的几率一次获得两个糖豆。 所以我们尝...原创 2019-03-28 19:07:31 · 232 阅读 · 0 评论 -
迭代器与组合模式
GitHub代码 迭代器模式 场景描述:我们目前正在吞并期,刚把一个煎饼店和一个餐厅兼并了。但是关于菜单的设计上好像遇到了写麻烦,两者采用的集合不同,一个用数组,一个用ArrayList。 尝试:如果我们想要打印菜单,就需要分别对两种不同的集合进行处理。 我们可以封装遍历吗?不论是那种集合,我们都可以统一进行处理。 这就需要引出迭代器了。 public interface Iterator { ...原创 2019-03-28 19:02:30 · 256 阅读 · 0 评论 -
模板方法模式
GitHub代码 场景描述:假设我们的咖啡馆拥有两种饮料的冲泡方法,但是它们的步骤是很类似的。因此我们想要将这种饮料冲泡法整合成一种模板式的方法,每种饮料仅针对其特定的调配模式自我实现。 我们目前设计如下 我们根据如上设计进行代码编写 首先在超类中定义模板方法 public abstract class CaffeineBeverage { final void prepareRecip...原创 2019-03-28 18:51:54 · 356 阅读 · 0 评论 -
适配器模式与外观模式
适配器GitHub代码 外观GitHub代码 适配器模式 场景描述:想象一下我们维护了一套老系统,并于一个厂商通过接口进行交互。但是最近厂商更新它们的代码,并变更了接口格式,我们如何在不修改老系统代码的基础上,优雅的过渡呢? 提出方案:我们可以想象一下我们平时使用的转换头,这就是一种适配器。我们可以通过这种方式来优雅的“将方形放入圆形中”。 我们尝试举一个例子,假设现在有一个鸭子接口 public...原创 2019-03-28 18:46:07 · 672 阅读 · 0 评论 -
命令模式
GitHub代码 场景描述:我们需要构建一个遥控器程序,它拥有几个插槽,而这些插槽可以配置不同功能的api,并且拥有一个撤销按钮,可以撤销上一次的操作。 第一构想:使用大段的if else做逻辑判断,但是这是一种非常糟糕的设计。 在提出改进方案之前,让我们看一个关于餐厅点餐的示例。 进而引申出命令模式 命令模式将“请求”封装成对象,以便使用不同的请求、队列或者日志参数化其他对象。命令模式也支...原创 2019-03-28 18:36:24 · 236 阅读 · 0 评论 -
单例模式
GitHub代码 场景描述:假设我们需要一个全局唯一的实例,比如线程池,缓存等。 初步解决:比如所有开发人员通过约定,或者全局变量来实现。 问题:将对象赋值给一个全局变量,但并不一定会立即使用它,从而占用内存资源,造成资源的浪费。 更好的方案:使用单例模式。 经典的单例模式代码如下: public class Singleton { private static Singleton uni...原创 2019-03-28 18:30:42 · 146 阅读 · 0 评论 -
工厂模式
GitHub代码 场景描述:我们正在设计一个披萨店,因为我们对披萨的操作有一套固有的流程,比如切割,装盒等,但是我们有着非常多的披萨类型,风味不同,所以如何设计针对不同口味创建不同的披萨就成了整个程序的难点。 简单工厂 为了增加程序的弹性,并且避免频繁修改代码,我们将变化的部分拿出去,创建了一个简单工厂类。 public class SimplePizzaFactory { public...原创 2019-03-28 18:26:21 · 205 阅读 · 0 评论 -
装饰者模式
GitHub代码 场景描述:咖啡店的订单系统,初始的类设计如下 现提供加入配料的服务,在原有的系统上进行扩展。 初次尝试:直接为每个组合创建一个类,带来的问题就是类的数量过多,且毫无弹性可言。 再次尝试:从基类Beverage下手,通过实例变量表示是否加上调料。 带来的问题:如果发生需求变动,比如调整调料价格,加入新的调料等等都会造成对原有代码的修改。也没有实现弹性设计。 设计原则:类应该...原创 2019-03-28 18:15:30 · 384 阅读 · 0 评论 -
观察者模式
GitHub代码 场景描述:我们得到了一个类WeatherData,它可以从气象站取得数据,现在需要我们实现measurementsChanged()方法,将数据更新到相应的布告板上。 初次尝试: public void measurementsChanged(){ float temp = getTemperature(); float humidity = getHumidit...原创 2019-03-28 18:06:36 · 266 阅读 · 0 评论 -
策略模式
GitHub代码 场景阐述:通过设计一个超类鸭子而让子类继承,提取出部分公共方法进行实现,但后续添加需求时,因为设计上的问题导致无穷无尽的噩梦…… 事出有因:超类鸭子负责实现公共的呱呱叫(quack)方法,后续提出需求,想要为鸭子加入fly方法以提高产品竞争力,但是由于技术失误,将此fly方法作为公共方法在超类鸭子中实现后,程序出现bug,橡皮鸭子也会飞啦! 改进策略:通过在橡皮鸭子中覆盖fly方...原创 2019-03-28 17:59:28 · 259 阅读 · 0 评论