1. 设计原则

  • 单一职责原则:一个对象或者一个方法只做一件事
    • 能够降低实体的复杂度,便于维护和拓展
    • 提高实体的可读性
    • 改动代码的风险降低了,也不会牵一发而动全身
  • 开闭原则:一个软件实体,如类、模块和函数应该对扩展开放,对修改关闭
    • 不会改变原有功能,从而引发故障
  • 里氏替换原则:所有引用基类的地方必须能透明地使用其子类的对象
    • 为继承定义了规范,实现更好的继承
  • 迪米特原则:如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。
    • 降低了类之间的耦合度,提高了模块的相对独立性。
    • 由于耦合度降低,从而提高了类的可复用率和系统的扩展性。
    • 过度使用会造成系统产生大量的中介类,从而增加系统的复杂度
  • 接口隔离原则:客户端不应该依赖它不需要的接口、类间的依赖关系应该建立在最小的接口上
    • 接口隔离提高了系统的内聚性,减少了对外交互,降低了系统的耦合性。
    • 将臃肿庞大的接口分解为多个粒度小的接口,可以预防外来变更的扩散,提高系统的灵活性和可维护性。
    • 能减少项目工程中的代码冗余
  • 依赖倒置原则:上层模块不应该依赖底层模块,它们都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。
    • 降低模块之间的耦合,同时便于功能的扩展

2. 设计模式

2.1 创建型模式

2.1.1 简单工厂模式

将创建对象的过程使用对象工厂封装起来,从而屏蔽了产品实现的具体细节,实现了代码层面的解耦,还减少了代码量。
简单工厂模式为每种对象创建一个工厂,通过传入参数实现生产,但这在一定程度上还存在调度和被调用之间的耦合。
故事1:我来到4S店来买车,**我说:“老板,给我来辆奥迪”。老板去汽车厂里调了一台奥迪来了,我又说,来一辆宝马,老板又去宝马车厂里调了一台宝马来了。**我又准备说,老板说等等,我好累,让我歇会。

2.1.2 工厂方法模式

工厂方法模式将工厂抽象化,通过在生产工厂类时就指定创建的对象,进一步降低了耦合,形成工厂—产品一一对应的模式,因此满足了“开放-封闭”原则。

故事2:老板嫌这样太麻烦了,每次都要我说他才去找人,老板说:小伙子你要啥车,我直接带你去汽车厂,你爱咋看咋看。就这样,我逛了两个汽车厂。

2.1.3 抽象工厂模式

抽象工厂在工厂方法的基础上进一步扩展了工厂的功能,此时工厂不仅仅能够生产一种产品,而是可以生产多种。:现在某个工厂并不仅仅生产宝马车,还生产宝马坐垫、宝马轮胎等
故事3:不过,我看了看汽车厂也太小了,只生产一个产品,感觉有点不对劲,汽车厂工人赶忙解释到,这只是一个分厂,其他分厂还生产其他产品呢。我说好吧,看着一辆好帅的奥迪车,大声说:“给爷来一辆奥迪车,就要这种的,不差钱”。

2.1.4 建造者模式

建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。其将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示
故事4:奥迪工厂夯吃夯吃地给我组装了一辆奥迪车,我夯吃夯吃地开走了,不过我没有发现这奥迪车是组装车,用的是宝马的轮子、奔驰的发动机。

2.1.5 单例模式

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。
故事5:原来我之前看到的奥迪车整个(假)奥迪工厂只有一辆,而我还蒙在鼓里。

2.1.6 原型模式

指用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。常用于创建某对象的代价比较大时,例如一个对象需要在一个高代价的数据库操作之后被创建。
故事6:事实上假奥迪工厂也不知道怎么造车,他们所有的车都是根据那辆真奥迪车复制过来的。

2.2 结构型模式

2.2.1 适配器模式

适配器模式就是在不改变原有结构和功能前提下,对类进行拓展(满足开闭原则),在继承原有类的基础上生成适配器类并实现对应接口,将现有类不能处理的请求,通过调用适配器类实现接口的方法进行完成
故事7:现在车有了,不过开车有点无聊,我准备播放CD,一找没找到车载CD机,这车咋和其他车不一样呢,没办法我去买了一个CD机放在车上,让它来播放CD。

2.2.2 装饰器模式

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。从而避免了创建过多子类,也避免了子类膨胀
故事8:我还要给车内加点内饰,让车子好看一点,我从商店里买一个布娃娃准备挂到车里,但是布娃娃的衣服不怎么好看,所以我给布娃娃上面套了一件裙子,这样它就更好看了。

2.2.3 桥接模式

桥接是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。
故事9:由于我很喜欢布娃娃,并且喜欢给不同的布娃娃穿上不同的裙子,我想凑齐7个娃娃,但是娃娃太贵我买不起那么多,我一想:“我买2个娃娃,4件衣服不就有8个娃娃了吗,我真是个天才!”,我开始动手了。

2.2.4 外观模式

外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。
故事10:我又觉得每次给娃娃换衣服太费劲了,我买了一个超级便宜的娃娃机,让娃娃机负责换衣服,我只需要告诉娃娃机我要穿什么衣服的什么娃娃就行了。

2.2.5 代理模式

代理模式的作用是为某对象提供一种代理以控制对该对象的访问。 即客户端通过代理间接地访问该对象,从而限制、增强或修改该对象的一些特性。
由于静态代理会导致类文件大量增多,所以 Java 中动态代理使用的较多。
故事11:我眉头一皱,发现事情并不简单,原来我的娃娃机之前是试用期,现在要收费了,想要不同的娃娃需要支付对应的金钱,当给钱越多时,给出的娃娃越好越漂亮。

2.2.6 享元模式

享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。
享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。
故事12:现在我有了娃娃机,但是每次买娃娃需要很多钱,所以我需要将娃娃保存起来,下次直接使用而不是去买,如果没有才要去买,恰巧娃娃机有一个娃娃盒子,可以放置我购买的娃娃。

2.2.7 组合模式

组合模式,就是在一个对象中包含其他对象,这些被包含的对象可能是终点对象(不再包含别的对象),也有可能是非终点对象(其内部还包含其他对象,或叫组对象),我们将对象称为节点,即一个根节点包含许多子节点,这些子节点有的不再包含子节点,而有的仍然包含子节点,以此类推。
组合模式将对象组成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
故事13:现在我有了好看的娃娃挂在车里,但是我觉得还是不够,我又去买了一个俄罗斯套娃,套娃套娃套娃~,瞬间我的奥迪车B格就上来了。

2.3 行为型模式

2.3.1 状态模式

状态模式(state pattern) 的定义:对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。
在状态模式(State Pattern)中,类的行为是基于它的状态改变的。这种类型的设计模式属于行为型模式。
故事14:现在布娃娃已经装到车上了,暂时够了,我决定开始我的极速之旅,这是我发现娃娃在不同速度时呈现的状态不一样,我匀速时娃娃正常,我加速时娃娃向后摆动,我减速时娃娃向前摆动。

2.3.2 责任链模式

责任链(Chain of Responsibility)模式的定义:为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。
故事15:走着走着,我在路上碰见我朋友了,我朋友说要借车用一下,并且带我去一个地方,我一个人不能决定,因此我要告诉我爸爸妈妈,如果他们同意的话我就去。

2.3.3 访问者模式

在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。
故事16:很高兴的是,我爸妈同意了,所以我决定把车借给我朋友,他一上车就对我的车发出了惊叹,轮胎好帅啊,娃娃好漂亮,坐垫好舒服。他摸了摸娃娃,坐上了坐垫。

2.3.4 命令模式

命令(Command)模式的定义如下:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。
故事17:现在我朋友开着我的车上路了,在路途中迷路了,于是其开启了导航。根据导航发出的命令,我朋友控制者车的移动。

2.3.5 解释器模式

解释器模式(Interpreter Pattern)提供了评估语言的语法或表达式的方式,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等
故事18:现在我们到达目的地了,原来这是一个宝藏秘境,宝藏守卫有三道难题,只有全部答出来,才能取得宝藏。
第一道题是在规定时间内完成100道计算题,题目是简单的四则运算,比如 30+410+50,我嘴角一咧:“瞧不起谁呢,分分钟搞定”。

2.3.6 观察者模式

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。
观察者模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
故事19:第二道题是宝藏秘境有一棵诡异的铁树和一座诡异的量子钟,铁树永远不会在注视下开花,量子钟必须在注视下才工作,现在宝藏守卫要求我们获得铁树开花时原子钟的正确时间。

2.3.7 策略模式

策略模式是对象的行为模式,用意是对一组算法的封装。动态的选择需要的算法并使用。
策略模式指的是程序中涉及决策控制的一种模式。策略模式功能非常强大,因为这个设计模式本身的核心思想就是面向对象编程的多形性思想。
故事20:第三个问题是给我们两个数,让我们使用最少次加减乘除后将一个数变成另一个数,记录变化的过程。遗憾的是,我们没有做出来这道题,因此与宝藏无缘了。 但作为答对前两题的奖励,我们获得了一个金属箱子,里面可能有宝物。

2.3.8 模板方法模式

模板方法模式定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
故事21:哎呀,好气啊,大宝藏没有拿到。但是我们记住了算法机器的特点,所以决定回去也仿制一个一模一样的,甚至更加强大的,说不定等哪天做出来了就能回来拿宝藏了。

2.3.9 备忘录模式

指在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
故事22:虽然说没有拿到宝藏,但是经历的这一切都是很有意义的,宝藏守卫拿出魔法相机,和我们合影以保存这一难忘时刻,当我们想起来答案时,对着照片大喊:“我是要成为海贼王的男人”,就可以直接传送到这里继续答题。

2.3.10 迭代器模式

提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。
故事23:我们离开宝藏秘境后,迫不及待的打开了金属箱子,箱子有3层,我们从第一层开始一层一层往下打开,发现了了不得的宝贝。

2.3.11 中介者模式

中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。
故事24:我们发现得到的宝物竟然是三本书,这可把我们气个半死,但当我定睛一看,这三本书竟然不是普通的教科书,而是很牛很牛的书,所以我们决定卖个好价钱,但是怕暴露自身而引来灾祸,我们决定找个中介来帮我们卖书。
最后3本书卖了3个亿人民币,我和我朋友一人1亿,最后过上了无忧无虑的幸福生活。(剧终)