开发者社区> 航空母舰> 正文

23种 设计模式---面向对象的基本原则

简介:
+关注继续查看

软件开发原则

原则1:不要重复自己(Don’t Repeat Yourself,DRY原则) 
这个原则非常重要,换言之,就是不要写重复的代码。

原则2:尽量简单、一目了然(Keep it Simple Stupid,KISS原则)

所以做到简单的同时,还要做到一目了然。你也可以这样理解,将一个软件做得连白痴都会用。这就是用户体验的最高境界了。如何做到简单且一目了然呢?这要归结到软件开发的可维护性和可理解性

原则3:适可而止(You Ain’t Gonna Need It,YAGNI原则) 
YAGNI原则指的是只需要将应用程序必需的功能包含进来,而不要试图添加任何其他你认为可能需要的功能。 在一个软件项目中,往往80%的时间花费在20%的功能上。当你准备列出一个项目清单时,试着考虑以下问题:
通过降低抽象的层级,来实现低复杂度,根据特性将功能独立出来,适度接受非功能性需求,识别耗时的任务,并摆脱它们

 

设计模式以前学了几个简单的Factory, Singleton等, 前一段时间决定系统的学习一下,耗时两个月, 读了3本书,包括<Java与模式>,<大话设计模式>, <head first design pattern>, 还参考了大量的网友的经验和思想, 最终把自己认为精华的部分,记录在blog中. 当然我自己也学的不是很深入, 需要在项目中逐渐体会, 同时也想多看看优秀的源码,它们都是设计模式非常好的教材. 所谓知之为知之, 不知为不知, 是知也.
需要提醒行业新朋友的是:  
1 设计模式不是新技术, 它是前人总结的软件设计思想. 这就好比盖楼房, 砖瓦结构可以盖, 框架结构也可以, 但是砖瓦结构肯定盖不了100层高楼.
2 设计模式不局限于语言 , java可以, c++,c# delphi可以, php, JavaScript也可以. 正如我不懂c#, 但是我读的<大话设计模式>却是以c#来讲解的, 但我觉得这不影响我理解设计模式.
3 学习设计模式不是不是把类图画出来就算学完了, 关键是看一个设计模式是怎么做到把握需求,拥抱变化的.

 

为什么要知道面向对象的基本原则呢? 因为我们考察一个设计模式好不好, 一个设计优秀不优秀, 用基本原则来检验.


单一职责原则(Single Responsibility Principle): 就是一个设计或实体应该只做一件事/只描述一个事物, 比如一个类Cat, 那么读代码的人应该觉得这个类始终都在说猫,而不是扯到狗身上去了, 虽然猫狗有时候会打架,但那也只是关联关系. 这与现实中也很相似, 如果你专著于一件事, 你会做得很出色.


开放封闭原则(Open-Close Principle): 一个实体应该对拓展开放,对修改封闭. 就是说, 任何一个系统, 需求总是在变的, 但是我们不能在任何需求到来的时候都把原有的设计推倒了重来, 而是尽可能的在保持相对稳定的情况下, 进行拓展. 事实上这也是世间万物的演变规律, 任何生物,都是从当初的单细胞生物随着环境的变化而逐渐演化过来的, 而不是说, 一旦环境变化, 则变异一个全新的形态出来. 在软件行业中, 这一原则体现在知识的积累, 系统的演化更新上. 优秀的平台(如java), 框架(如struts, spring), 都是由最初的雏形, 从版本0.1开始演化过来.


里氏替换原则(Liskov Substitution Principle): 子类必须能够替换掉他们的父类型. 这个原则考验的是继承结构的合理性, 如果子类不能完全取代父类的位置, 则继承结构就不合理.
依赖倒置原则(Dependency Inversion Principle): 设计应该依赖于抽象,而不能依赖于具体。也就是说要面向接口编程。 因为接口代表着功能,代表着规范,不易变。而实现却会随着时间和环境发生变化。比如银行,自从有银行开始,它就有存款和贷款业务, 那么存款和取款就是它的接口。但是不同的时代,具体的实现方式大有不同,以前都要到银行柜台上去办理, 后来有了支票, 现在有了电子帐户。如果我们有一个设计要使用银行的业务,不应该依赖于具体的某种实现方式,而应该依赖于接口。

接口隔离原则(Interface Seperation Principle): 使用多个专门的接口比使用单一的总接口要好. 系统对外提供宽窄不同的接口以应对不同的客户。

1.单一职责原则(SRP)

单一职责原则的核心思想就是:系统中的每一个对象都应该只有一个单独的职责,而所有对象所关注的就是自身职责的完成。它的英文缩写是SRP,英文全称是Single Responsibility Principle。

其实单一职责原则的意思就是开发人员经常说的"高内聚、低耦合"。也就是说,每个类应该只有一个职责,对外只能提供一种功能,而引起类变化的原因应该只有一个。在设计模式中,所有的设计模式都遵循这一原则。

2.开闭原则(OCP)

开闭原则的核心思想就是:一个对象对扩展开放,对修改关闭。它的英文缩写是OCP,英文全称是Open for Extension,Closed for Modification。

其实开闭原则的意思就是:对类的改动是通过增加代码进行的,而不是改动现有的代码。也就是说,软件开发人员一旦写出了可以运行的代码,就不应该去改变它,而是要保证它能一直运行下去,如何才能做到这一点呢?这就需要借助于抽象和多态,即把可能变化的内容抽象出来,从而使抽象的部分是相对稳定的,而具体的实现层则是可以改变和扩展的。

3.里氏替换原则(LSP)

里氏替换原则的核心思想就是:在任何父类出现的地方都可以用它的子类来替代。它的英文缩写是LSP,英文全称是Liskov Substitution Principle。

其实里氏替换原则的意思就是:同一个继承体系中的对象应该有共同的行为特征。里氏代换原则关注的是怎样良好地使用继承,也就是说不要滥用继承,它是继承复用的基石。

4.依赖注入原则(DIP)

依赖注入原则的核心思想就是:要依赖于抽象,不要依赖于具体的实现。它的英文缩写是DIP,英文全称是Dependence Inversion Principle。

其实依赖注入原则的意思就是:在应用程序中,所有的类如果使用或依赖于其他的类,则都应该依赖于这些其他类的抽象类,而不是这些其他类的具体实现类。抽象层次应该不依赖于具体的实现细节,这样才能保证系统的可复用性和可维护性。为了实现这一原则,就要求开发人员在编程时要针对接口编程,而不针对实现编程。

5.接口分离原则(ISP)

接口分离原则的核心思想就是:不应该强迫客户程序依赖它们不需要使用的方法。它的英文缩写是ISP,英文全称是Interface Segregation Principle。

其实接口分离原则的意思就是:一个接口不需要提供太多的行为,一个接口应该只提供一种对外的功能,不应该把所有的操作都封装到一个接口当中。

6.迪米特原则(LOD)

迪米特原则的核心思想就是:一个对象应当对其他对象尽可能少的了解。它的英文缩写是LOD,英文全称是Law of Demeter。

其实迪米特原则的意思就是:降低各个对象之间的耦合,提高系统的可维护性。在模块之间,应该只通过接口来通信,而不理会模块的内部工作原理,它可以使各个模块耦合程度降到最低,促进软件的复用。

7.优先使用组合而不是继承原则(CARP)

优先使用组合而不是继承原则的核心思想就是:优先使用组合,而不是继承。它的英文缩写是CARP,英文全称是Composite/Aggregate Reuse Principle。

其实优先使用组合而不是继承原则的意思就是:在复用对象的时候,要优先考虑使用组合,而不是继承,这是因为在使用继承时,父类的任何改变都可能影响子类的行为,而在使用组合时,是通过获得对其他对象的引用而在运行时刻动态定义的,有助于保持每个类的单一职责原则。


更多原则不一一细说. 而且如果没在实践中体会他们, 记住文字定义也没有意义.

创建型:

1. 单件模式(Singleton Pattern)

2. 抽象工厂(Abstract Factory)

3. 建造者模式(Builder)

4. 工厂方法模式(Factory Method)

5. 原型模式(Prototype)

结构型 :

6. 适配器模式(Adapter Pattern)

7. 桥接模式(Bridge Pattern)

8. 装饰模式(Decorator Pattern)

9. 组合模式(Composite Pattern)

10. 外观模式(Facade Pattern)

11. 享元模式(Flyweight Pattern)

12. 代理模式(Proxy Pattern)

13. 模板方法(Template Method)

14. 命令模式(Command Pattern)

15. 迭代器模式(Iterator Pattern)

行为型 :

16. 观察者模式(Observer Pattern)

17. 解释器模式(Interpreter Pattern)

18. 中介者模式(Mediator Pattern)

19. 职责链模式(Chain of Responsibility Pattern)

20. 备忘录模式(Memento Pattern)

21. 策略模式(Strategy Pattern)

22. 访问者模式(Visitor Pattern)

23. 状态模式(State Pattern)

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Java 8 Lambda 表达式相关
Java 8 之后推出的 Lambda 表达式开启了 Java 语言支持函数式编程(Functional Programming)的新时代。 Lambda 表达式,也称为闭包(Closure),现在很多语言都支持 Lambda表达式,如 C++、C#、Swift、Objective-C 和 JavaScript 等。为什么 Lambda 表达式这怎么受欢迎,这是因为Lambda表达式是实现支持函数式编程技术基础。 函数式编程与面向对象编程有很大的差别,函数式编程将程序代码看作数学中的函数,函数本身作为另一个函数的参数或返回值,即高阶函数。而面向对象编程是按照真实世界客观事物的自然规律进行分析,
6 0
05 Java 类和对象
面向对象是 Java 最重要的特性。Java 是彻底的、纯粹的面向对象语言,在 Java 中“一切都是对象”。本章将介绍面向对象基础知识。 面向对象 • 相对面向过程而言, 面向对象和面向过程都是一种思想 • 将功能封装进对象,强调具备了功能的对象。 • 是一种符合人们思考习惯的思想, 可以将复杂的事情简单化, 将程序员从执行者转换成了指挥者.
5 0
09 枚举类
枚举概述 枚举用来管理一组相关常量的集合,使用枚举可以提高程序的可读性,使代码更清晰且更易于维护。 在 Java 5 之前没有提供枚举类型,可以通过声明静态常量(final static 变量)替代枚举常量。 通常在接口中声明一组静态常量,当然也可以在一般类中声明一组静态常量。这些常量往往都是 int 类型,这是为了以后方便使用 switch 语句进行判断。
4 0
20 Java 使用反射(Reflection) 和内省技术
反射(Reflection)是程序的自我分析能力,通过反射可以确定类有哪些方法、有哪些构造方法以及有哪些成员变量。Java语言提供了反射机制,通过反射机制能够动态读取一个类的信息;能够在运行时动态加载类,而不是在编译期。反射可以应用于框架开发,它能够从配置文件中读取配置信息动态加载类、创建对象,以及调用方法和成员变量。
3 0
07 接口和抽象类
接口 比抽象类更加抽象的是接口,在接口中所有的方法都会被 public abstract 修饰。 注意:Java 8 之后接口中新增加了 default 默认方法和 对 static 方法的支持。 • Java 中不支持多继承,而是通过接口实现比多重继承更强的功能,java 通过接口可以使出于不同层次,甚至不相关的类具有相同的行为. • 接口可以认为是特殊的抽象类, 不能用于直接创建对象。接口的作用在于规定一些功能框架,具体功能的实现则通过该接口约束的类完成。
2 0
06 Java 的继承
继承 Java 继承的实现(只支持类的单继承,不支持类多继承,但是支持接口的多实现)。 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类. 定义类时直接通过 extends 关键字指明要继承的父类。
3 0
1. 初步规划
因为目前正从事测试平台开发的相关工作,但是苦于市场上的大多数产品的针对性太强,或多或少没有一个通用的方案。于是想利用自己的空余时间,写一个web测试平台,也顺便记录下自己的学习历程。至于是否太监,就不得而知了。先暂且将他命名为lamb吧~~
3 0
【Kotlin 初学者】函数(方法)(下)
函数 函数(function)和方法(method)这两个概念经常被混淆,他们到底有什么关联和区别?其实,它俩没有什么区别只是不同语言叫法不一样,在Java中普遍叫方法。而在Kotlin中普遍叫函数。重点是:函数(function)和方法(method)是同一个东西,别搞错了。
4 0
11.1 Java 详解 Object 和包装类
java.lang.Object 类 所有 Java 类的最终祖先,编译系统默认继承 Object 类,Object 类包含了所有 Java 类的公共属性和方法。 • Object(): 构造方法 • getClass():Class<?> • public boolean equals(Object obj) :该方法本意用于两个对象的“深度”比较,也就是比较两对象封装的数据是否相等;而比较运算符“==”在比较两对象变量时,只有当两个对象引用指向同一对象时才为真值。但在Object类中,equals方法是采用“==”运算进行比较; • hashCode() • public String t
3 0
Java 总结 数据的输入/输出
标准输入输出流 字符输入: char c = (char)System.in.read(); 字符串输入: BufferedReader buf = new BufferedReader(new InputStreamReader(System.in)); String str = buf.readLine(); 使用System.out输出 (标准输出流 System.out )提供的如下方法 print()方法:实现不换行的数据输出; println()方法:与上面方法的差别是输出数据后将换行。 printf()方法:带格式描述的数据输出。该方法包含两个参数,第一个参数中给出输出格式的
5 0
+关注
514
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载