浅析设计模式

不知道你有没有这种经历?

某次面试的时候经常会被面试官问道什么是设计模式? 常用的设计模式是什么?请结合你的项目说说为什么要使用设计以及使用设计模式所带来的好处? 大概知道但是又说不上个所以然,真TM尴尬。为了避免这种事情再次发生,我决定通过自己的理解,搞一个专题(今天只是概念性的东西,后面我会通过代码来实现每个设计模式),来记录与总结我遇到的问题来帮助有需要的人,如有错误的地方请各位大神及时指教,小弟不胜感激!

问题一: 什么是设计模式?

设计模式是软件设计中常见问题的典型解决方案。 它们就像能根据需求进行调整的预制蓝图,可用于解决代码中反复出现的设计问题。

设计模式与方法或库的使用方式不同, 你很难直接在自己的程序中套用某个设计模式。 模式并不是一段特定的代码,而是解决特定问题的一般性概念。你可以根据模式来实现符合自己程序实际所需的解决方案。

人们常常会混淆模式和算法,因为两者在概念上都是已知特定问题的典型解决方案。但算法总是明确定义达成特定目标所需的一系列步骤,而模式则是对解决方案的更高层次描述。同一模式在两个不同程序中的实现代码可能会不一样。

算法更像是菜谱:提供达成目标的明确步骤。而模式更像是蓝图:你可以看到最终的结果和模式的功能,但需要自己确定实现步骤。

通俗点说,模式就是先辈程序员(那些老不死的大牛)针对开发中遇到的问题提出的大家公认且行之有效的解决方案。

问题二: 学习设计模式的意义

设计模式的本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性以及类的关联关系和组合关系的充分理解。正确使用设计模式具有以下优点。

1、可以提高程序员的思维能力、编程能力和设计能力。
2、使程序设计更加标准化、代码编制更加工程化,使软件开发效率大大提高,从而缩短软件的开发周期。
3、使设计的代码可重用性高、可读性强、可靠性高、灵活性好、可维护性强。

问题三: 模式包含哪些内容?

大部分模式的描述都会遵循特定的形式,以便在不同情况下使用。模式的描述通常会包括以下部分:

意图· 部分简要地描述问题和解决方案。
动机· 部分进一步解释问题并说明模式会如何提供解决方案。
结构· 部分展示模式的各个部分和它们之间的关系。

问题四:模式的分类:

不同的设计模式在其复杂程度、细节层次以及在整个系统中的应用范围等方面各不相同。

 惯用技巧· 最基础的、底层的模式通常被称为惯用技巧,这类模式一般只能在一种编程语言中使用。
架构模式· 最通用的、高层的模式是架构模式,开发者可以在任何编程语言中使用这类模式。与其他模式不同,它们可用于整个应用程序的架构设计。(如:MVC、MVVM、分层模式、代理模式等)

此外, 所有模式可以根据其意图或目的来分类。分为以下三类:

 创建型模式· 提供创建对象的机制, 增加已有代码的灵活性和可复用性。
结构型模式· 介绍如何将对象和类组装成较大的结构,并同时保持结构的灵活和高效。
行为模式·   负责对象间的高效沟通和职责委派。

问题五: 软件设计原则(SOLID):

这个设计原则就是我们通常说的单一职责、开闭原则等五个,以下为详细的描述

S· 单一职责原则 Single Responsibility Principle

修改一个类的原因只能有一个。

尽量让每个类只负责软件中的某一个特定的功能,并将该功能完全的封装(你也可称之为隐藏) 在该类中。

这条原则的主要目的是减少复杂度。你不需要费尽心机地去构思如何仅用 200 行代码来实现复杂设计,实际上完全可以使用十几个清晰的方法。

当程序规模不断扩大、变更不断增加后,真实问题才会逐渐显现出来。到了某个时候, 类会变得过于庞大,就导致查找或者修复某一个功能时特别复杂。

还有一点: 如果类负责的东西太多,那么当其中某一功能发生改变时,你都必须对类进行修改而在进行修改时,你就有可能改动类中自己并不希望改动的部分。

O· 开闭原则 Open/closed Principle

对于扩展,类应该是 “开放” 的;对于修改,类则应是 “封闭” 的。

本原则的主要理念是在实现新功能时能保持已有代码不变。

如果你可以对一个类进行扩展,可以创建它的子类并对其做任何事情 (如新增方法或成员变量、重写基类行为等),那么它就是开放的。

如果某个类已做好了充分的准备好并可供其他类使用的话 (即其接口已明确定义且以后不会修改),那么该类就是封闭的。

L· 里氏替换原则 Liskov Substitution Principle

扩展一个类时,应该要能在不修改客户端代码的情况下将子类的对象作为父类对象进行传递。(这个有点抽象啊,老铁们?)

子类方法的参数类型必须与其超类的参数类型相匹配或更加抽象(比如父类是“机动车”,那么子类可以是具体的某种机动车,如:宝马、兰博基尼甚至是农用三轮车等)

子类方法的返回值类型必须与超类方法的返回值类型或是其子类别相匹配(如:父类返回的是宝马品牌的汽车,那么子类可以返回X3、X5、X7、GT等都是属于宝马的)

子类中的方法不应抛出基础方法预期之外的异常类型。

子类不应该加强其前置条件。

子类不能削弱其后置条件。

超类的不变量必须保留。

子类不能修改超类中私有成员变量的值。

I· 接口隔离原则 Interface Segregation Principle

客户端不应被强迫依赖于其不使用的方法。

尽量缩小接口(协议)的范围, 使得客户端的类不必实现其不需要的行为。

D· 依赖倒置原则 Dependency Inversion Principle

高层次的类不应该依赖于低层次的类。两者都不应依赖于抽象接口。抽象接口不应依赖于具体实现。具体实现应该依赖于抽象接口。

今天这些概念摘抄自很多地方,以方便开头。接下来每一种模式我都会附带代码进行理解和解读。

不管我们遇到什么困难,也不要怕,微笑着面对它,消除恐惧的最好办法就是面对恐惧,坚持,才是胜利,加油,奥利给!!

原文:https://juejin.im/post/6844904039151304718

- Posted in: Columns

- Tags:

0 条评论 78 次阅读

  1. 既来之,则言之。

发表评论

Top