欢迎光临散文网 会员登陆 & 注册

2.5 用上设计模式你就厉害了?

2023-05-23 20:23 作者:xlorne  | 我要投稿

为什么用了设计模式后反而没有那么厉害?

1. 为了用而用

首先想要使用上某个设计模式,然后就修改代码让其使用上。比方说为了将采用策略模式,而修改代码使其可以使用上策略模式,这就是为了用上设计模式而用上设计模式。

假设我们有一个动物园,目前里面只有狮子和老虎,我们需要让它们发出叫声。

如果我们采取直观的方法,我们可以创建一个 Animal 类,并为每种动物定义一个子类:

这样,我们可以让每个动物发出叫声:

但是,如果我们强制使用策略模式,我们需要首先定义一个策略接口,然后为每种动物的叫声创建一个策略:

然后,我们可以像这样使用它:

虽然策略模式提供了一种更灵活的方式来管理动物的叫声,但在这种情况下,它却引入了不必要的复杂性。在这个简单的例子中,使用策略模式并没有带来实际的好处,反而使代码变得更难理解。这就是“为了使用设计模式而使用设计模式”的问题所在。

2. 过度设计

有时候,为了提高扩展性,可能会过度使用设计模式,造成“过度设计”。这可能会使代码变得冗余和复杂,反而降低了代码的可读性和可维护性。

例如说用户的点击操作记录统计功能,为了未来可能的扩展性,你可能考虑使用观察者模式,让其他对象可以在用户点击时接收到通知。

然后在主程序中,你可能这样使用:

虽然这个设计可以让你在未来很容易地添加更多的观察者,但是如果你从来不需要添加其他观察者,那么这个设计就显得过度了。其实,一个简单的整数变量就可以满足你记录点击次数的需求,无需引入观察者模式的复杂性。

3. 预先优化

经常为了未来的需求做考虑,然后基于未来的需求做抽象设计,然后引入了设计模式。必然说,需要实现一个加法运算,那你直接写一个加法函数即可,不需要为了这一个功能点直接开发一个计算器。

但是,如果过度设计,你可能会采用策略模式,来设计一个更抽象的计算器:

虽然这个设计看起来非常灵活,你可以通过修改 CalculatorOperation 来改变其行为,但是如果你只需要执行加法运算,这个设计显然过于复杂。过度设计往往会使代码变得更难理解和维护,所以在做设计决策时,我们需要找到复杂性和灵活性之间的平衡。


关于使用设计模式的建议

  1. 清晰的项目结构: 在考虑引入设计模式前,确保你的项目业务模型和结构是清晰的。如果你的代码是基于面向过程,缺乏适当的封装和抽象,那么引入设计模式可能会使代码更加复杂,反而不利于维护。

  2. 目标是为了可维护与可拓展: 设计模式应当被用来提高代码的可维护性和可扩展性。如果引入设计模式并未达到这样的效果,那么可能需要重新考虑你的设计。

  3. 避免过度设计和预先优化: 你应该试图满足当前的需求,而不是过度设计以满足可能的未来需求。过度追求设计模式可能导致过度设计,这可能会使代码变得不必要的复杂和难以理解。

  4. 理解设计模式的意图和原理,使用设计模式之前,确保你理解其意图和原理,而不仅仅是如何实现它。设计模式并不是代码模板,而是用来解决特定设计问题的通用解决方案。理解设计模式的背后原理,可以帮助你判断何时应该使用它,以及如何根据具体情况调整它。

  5. 设计模式应用需要适度: 设计模式的应用是为了解决实际问题,而不是为了让代码看起来“专业”或“复杂”。如果在不需要的情况下使用设计模式,或者过度使用设计模式,可能会使代码变得不必要的复杂和难以理解。

  6. 考虑团队因素: 如果你的团队成员对某种设计模式不熟悉,那么在项目中引入这种设计模式可能会带来问题。在决定使用哪种设计模式时,你需要考虑到团队成员的知识和技能。

  7. 重构是持续的过程: 在软件开发过程中,随着需求的变化和项目的发展,可能需要对代码进行重构。在这个过程中,可能会发现一些设计模式的应用场景。因此,不需要一开始就强求使用设计模式,而是在重构过程中逐步引入。

设计模式介绍

设计模式通常被归类为创建型、结构型和行为型三大类,各有不同的目标和应用场景。

以下是对这23种设计模式的归类和简单总结:

创建型模式

这类模式的主要关注点是如何创建对象,特别是在系统要求对创建过程进行更多控制和管理时。

  1. 单例模式:确保一个类只有一个实例,并提供全局访问点。

  2. 原型模式:使用复制现有对象的方式来创建新对象。

  3. 建造者模式:分离对象的构建和表示,同样的构建过程可以创建不同的表示。

  4. 工厂方法模式:定义一个创建对象的接口,但让子类决定要实例化哪个类。

  5. 抽象工厂模式:提供一个接口以创建一系列相关或依赖对象,而无需指定具体的类。

结构型模式

这类模式关注如何组织不同的对象和类以形成更大的结构,同时保持结构的灵活和高效。

  1. 适配器模式:使接口不兼容的类可以一起工作,将一个类的接口转换为客户希望的另一个接口。

  2. 桥接模式:将抽象和实现解耦,以便两者可以独立变化。

  3. 组合模式:允许将对象组合成树形结构以表示"部分-整体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性。

  4. 装饰模式:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。

  5. 外观模式:为一组接口提供一个统一的高层接口,使得使用更为方便。

  6. 享元模式:运用共享技术来有效地支持大量细粒度的对象。

  7. 代理模式:为其他对象提供一种代理以控制对这个对象的访问。

行为型模式

这类模式关注对象之间的通信,它们主要解决的是"对象如何、何时、以何种方式进行交互"的问题。

  1. 模板方法模式:定义算法的框架,而将一些步骤的实现延迟到子类。

  2. 访问者模式:为一个对象结构中的元素提供新的操作而不改变其类的结构。

  3. 迭代器模式:提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。

  4. 观察者模式:定义对象间的一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

  5. 中介者模式:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

  6. 命令模式:将一个请求封装为一个对象,从而使用户可以使用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

  7. 状态模式:允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。

  8. 策略模式:定义一系列的算法,把它们一个个封装起来,并且使它们可以互相替换。

  9. 责任链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。

  10. 备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后恢复对象到这个状态。

  11. 解释器模式:给定一个语言,定义它的语法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

2.5 用上设计模式你就厉害了?的评论 (共 条)

分享到微博请遵守国家法律