【软件开发】设计模式个人解读

【软件开发】设计模式个人解读

设计模式

设计模式是一种针对面向对象语言的软件设计方法,是对类设计的约束和指导。

设计模式由“原则”和“方法”两部分组成,一个设计良好的项目结构应能完美符合“原则”中的要求,而为了实现完美往往需要按照“方法”的指导去设计。

  • 原则:
    这是必须要记住的内容,但要注意的是原则是一种思想,仅靠死记硬背一点用都没有,必须要真正理解后才能使用。
  • 方法:
    方法在各个不同的开发环境中可能会有所区别,所以仅是一种参考,具体还需要配合相关原则因地制宜的使用,若不知其意却强行使用结果只会东施效颦。而且只要真正理解了设计原则,并且对编程语言足够熟悉的话,设计方法是可以自己推导出来的,所以若是特意要去背着玩意我觉得有点吃力不讨好。

设计原则

对于一个设计良好项目所应具有的特征,设计模式提出了7点原则。

一、开闭原则

这是设计模式最根本的原则,可以说其他原则也都是为满足这一原则而产生的,同时这也是面向对象方法的特点和优势,正因为面向对象语言中的种种特性开闭原则才得以实现。

程序的功能扩展不能以直接修改源代码的方式进行。

程序出Bug的根本原因就是增改代码,只要现有代码被改动就可能导致出错,如果代码间存在耦合那其他功能也必然会受到牵连,而且这种方式对团队协作也很不友好。

所以通过直接改原代码来扩展功能是很不明智的,为此我们要发挥面向对象方法,另辟蹊径的解决它,而在设计对象时按以下原则进行,可以更好的满足需求。

设计父子关系(继承方案)

二、里氏替换原则

确保任何基类可以出现的地方,一定可以子类实现并代替,且替换后子类不会影响原功能的运行。

利用继承和多态,我们便可以实现完全不动老代码方式扩展功能,从而满足开闭原则,而针对这种编程方式,我们给它命名为“面向接口编程”,而针对面向接口编程的设计方案又给我们带来了下面的这些原则。

三、依赖倒转原则

如果某功能存在扩展的需求,那我们应当将这部分代码接口化来隐藏细节,实现让功能依赖于接口而非实现。

实现不再被依赖,所以它可以成为一个个独立自由的个体,我们可以很方便很安全的进行开发和修改,且不会干扰到原有模块,因为他们只认接口而非实现。

四、接口隔离原则

在设计接口时应保证模块化,保证任何接口内容的使用都是必要的。

面向接口编程时,在设计上应尽可能保证提供多个相互独立的接口,而非臃肿的一整块,这可以减少耦合性,不然这些接口反而会成为累赘,逼着别人违反单一职责原则。

设计对象关系(组合方案)

五、合成复用原则

实现功能复用时优先采用组合或聚合,其次才考虑继承。

继承仍然会产生耦合性,子类将无法摆脱父类的存在,在部分开发框架下还会水土不服(如Unity中替换父子组件依旧需要删除重建),所以合成复用原则引导我们使用另一种解决方案“组合”。

组合是直接通过增设更多的功能模块从而实现功能的扩展,它不受一些继承问题带来的限制,产生的耦合性也小的多,而具体的模块设计方案,则引出了下面的原则。

六、单一职责原则

每个模块都应该仅负责少量且专精的功能(模块内高内聚)。

七、最少知道原则(迪米特原则)

一个模块应尽可能减少对其他模块的使用,使系统功能相对独立(模块间低耦合)。

设计方法

创建型模式(5):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式(7):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式(11):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

附录

Unity中采用设计模式的例子?

Unity框架中,所有碰撞体都继承了Collider类,通过里氏替换原则,子类得以可以自由扩展功能,且Unity还不需要做任何额外工作,一套旧代码就能处理任何新子类。

不同碰撞体间的差异需求导致产生了诸如BoxCollider,SphereCollider等子类,这些子类符合单一职责原则和最少知道原则,仅额外简单的实现了些形状上的差异,所以开发和使用时也不会相互影响。

但一个刚体往往需要的形状是非常复杂的,上述这些碰撞体由于过于简单都无法满足需求,此时Unity便采用组合的方式,支持将不同碰撞体同时使用,这样不需要写任何代码就能随意搭配更复杂的碰撞形状来。

假如不采用上述方案,那每一个子类都要单独写处理的代码,每一个新需求又会导致要重新写一个新子类,一两个还好,要是几十几百个,那项目维护开发绝对是灾难性的。

为什么设计模式中只提到了类和接口而没提事件委托?

虽然上文只提到了类和接口,但实际上包括一些语言中的委托事件这些都应该算在内,因为它们都有一个共同特点就是都有将算法的一部分参数化的功能。那为何此处只提到了类和接口呢?如果使用过java就很容易理解了,因为java中不存在委托类型,到处使用的都只有接口和匿名类,而它们其实就是委托事件的前身。


【软件开发】设计模式个人解读
https://bdffzi-blog.pages.dev/posts/2553791405.html
作者
BDFFZI
发布于
2024年1月14日
许可协议