包含标签 设计模式 的文章

工厂模式 Factory Pattern

工厂模式定义了一个创建对象的接口,但由子类决定要实例化的类时哪一个。工厂方法让类把实例化推迟到子类。 简单工厂 简单工厂的思路也确实非常简单,就像将创建类的代码进行了简单的抽离。《设计模式》也说这不应该算一种模式,更像一种编程习惯。就好比撸完代码之后自己回头看看,发现这一块独立的逻辑可以抽离出来独立一下。 工厂模式 工厂模式中,创建者与产品为平行类层级,只是创建者的创建方法产生产品。要创建哪种产品,由具体的创建者子类决定;产品的实际创建,也由产品的具体实现类完成。 代码 略……

阅读全文

状态模式 State Pattern

状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。 工作中经常会遇到各种状态机,使用流程控制的方式虽然也可以实现,但后续的维护变动就变得很困难。在实际中我们现在就遇到了一个这样子的问题,整个状态机的代码有一千多行,代码完成的还算工整,但要看懂现在就只能对比状态图了,因为状态实在太多了。我曾经增改过两次,每次改动都伴随着一大堆的问题单。 这时候就真真切切体会到状态模式的好处了。 类图 状态模式 vs 策略模式 如果与策略模式的类图对比的话,会发现图结构几乎一模一样。虽然如此,这俩模式还是有比较明显的区别。 策略模式中,最后的每一个业务类只包含了一组算法中的一个实现;或者说每一种算法的组合形成了一个业务类。 但在状态模式中,业务类中继承了算法的所有实现,并且在运行态切换算法为不同的实现,从而让自己拥有不同的行为(表现为不同的状态)。 我觉得类比之前策略模式中不同种类鸭子的实现,状态模式只存在一只百变鸭,但这只鸭子根据外界输入一会将自己变成红头鸭吱吱叫,一会儿变成绿头鸭呱呱叫。 代码 略……

阅读全文

工具篇

曾经信心满满的立过很多flag,要学习并掌握某一领域或坚持某件事儿,最终都无疾而终,只剩下零星概念和一堆遗憾,原因大都类似: 计划被其它事情打断,中止了 进行到一半,发现意义不大 进行中遇到了困难,放弃了 当时掌握了,但没有及时总结,后续没有练习,忘记了 包括不限于协议栈、数据库、JVM、正则表达式、音律、写总结……也包括设计模式。结果一回头,猛然发现时间已经过去了这么久,却什么都没有留下来。 在此再立一个flag,每周写一篇总结。周积跬步,以致千里。 UML 统一建模语言 (Unified Modeling Language, UML) 所有介绍设计模式的资料都会用到uml图。之前总以为UML图就是类图,每次都是被继承,实现里面的实线、虚线、箭头等给整懵了。然后就放弃看图,只看代码实现。 现在才知道,类图只是UML中的一小部分。UML图还包括用例图,时序图等。和SE等大佬交流时,设计文档里全是各种UML图。 PlantUML 各种工具都可以画UML图,包括visio,Visual Paradigm等。我们使用PlantUML, 像Markdown一样,通过简单的语句写UML图,使用方便。当然,这一套工具也都是免费的。 windows安装 PlantUML PlantUML有IntelliJ IDEA的插件版,可以直接在IDEA的plugins中下载安装。我们也使用这个版本。 插件装好之后,新建puml文件,直接打开就可以看到对应的编辑器了。 Graphviz 安装插件之后,也可能无法看到右边的预览图,而是提示报错,这是因为缺少Graphviz环境变量。Graphviz是一个开源的绘图软件,很多开源软件生成可视化图时都使用Graphviz。 下载Graphviz并安装后,配置如下环境变量之后就好了。 GRAPHVIZ_DOT=D:\Program Files (x86)\Graphviz2.38\bin\dot.exe PlantUML基本语法 PlantUML类图 泛化,Generalization 关联,Association 组合,Composition 聚合,Aggregation 实现,Realization 依赖,Dependency @startuml Class01 <|-- Class02:泛化 Class03 <-- Class04:关联 Class05 *-- Class06:组合 Class07 o-- Class08:聚合 Class09 <|.. Class10:实现 Class11 <.. Class12:依赖 @enduml ……

阅读全文

策略模式 Strategy Pattern

策略模式定义了算法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。 类图 继承 vs 组合 上面的描述有些抽象。策略模式想要表达的是,如果一个类需要某种行为,不要通过继承来实现(is-a),可以使用组合(has-a)来实现。这样做更加灵活,当业务类(duck)的行为(fly)需要改变时,只需要注入不同的算法实现类即可。 这也就是 鸭子继承, 如果一个类通过组合获取了鸭子的行为,那它就可以当作鸭子使用,不需要关注它是否继承自鸭子基类,是否真正的是一只鸭子。 Java中Spring的依赖注入(DI)也是这种思路。Golang中甚至取消了继承,从语法层面避免继承所带来的耦合。这里甚至可以推测,OOP在提出之初,只是基于对真实世界中对象建模的思路,提出了继承,实现等概念。但后续工程实践发现继承并没有组合好用。 很多协议设计也是这样,基于最初的构想设计了很多特性,结果后续使用中发现一部分设计很鸡肋或很容易出错。于是又通过各种约定,最佳实践,框架等来解决这些问题。 代码 public interface FlyBehavior { void fly(); } class FlyWithWings implements FlyBehavior { @Override public void fly() { // todo } } class FlyNoWay implements FlyBehavior { @Override public void fly() { // do nothing } } public interface QuackBehavior { void quack(); } class Quack implements QuackBehavior { @Override public void quack() { // todo } } class Squeak implements QuackBehavior { @Override public void quack() { // todo } } class MuteQuack implements QuackBehavior { @Override public void quack() { // todo } } public abstract class Duck { FlyBehavior flyBehavior; QuackBehavior quackBehavior; abstract void display(); void performFly() { flyBehavior.……

阅读全文