java中的设计模式及其六大原则
设计模式分类:
一共分为3大类:创造型模式、结构型模式、行为型模式。
创造型模式:工厂方法(FactoryMethod)、抽象工厂模式(AbstractFactory)、建造者模式(Builder)、单例模式(singleton)、原型模式(prototype)。
结构型模式:适配器模式(adapter)、桥接模式(Bridge)、组合模式(Composite)、装饰者模式(Decorator)、外观模式(Facede)、享元模式(Flyweight)、代理模式(Proxy)
行为模式:责任链模式(Chain of Responsibility)、命令模式(Command)、解释器模式(Interpreter)、迭代器模式(Iterator)、中介者模式(Mediator)、备忘录模式(Memento)、
观察者模式(Observer)、状态模式(State)、策略模式(Strategy)、模板方法模式(TemplateMethod)、访问者模式(Visitor)。
单一职责原则:
定义:不要存在多于一个导致类变更的原因。
通俗地说:一个类只负责一项职责。
问题来源:一个类T负责两个职责:职责1和职责2,当因为职责1因需求变化时,可能会导致职责2的功能发生故障。
解决方案:遵循单一职责原则,分别建立两个类:T1负责职责1,T2负责职责2。这样当因需求修改类时就不会导致别的功能出现异常。
看似简单但实际上因为开发时间的不同,或者是业务需求的变化可能会导致本来符合单一职责原则的类变得不符合这一原则。
所以涉及到开发或模块涉及时尽量将业务逻辑简单化,细分化。这样出现问题的时候,在做添加的时候,可以避免耦合过高影响其他功能的情况出现。
优点:
- 可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多;
- 提高类的可读性,提高系统的可维护性;
- 变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响。
需要说明的一点是单一职责原则不只是面向对象编程思想所特有的,只要是模块化的程序设计,都适用单一职责原则。
里氏替换原则:
定义1:如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型。
(这个定义,我表示。。。。。。。。)
定义2:所有引用基类的地方必须能透明地使用其子类的对象。
定义3:子类型必须能够替换掉它们的父类型。
大众点的感觉:子类可以扩展父类的功能,但是不能改变父类的功能。(如果改变了父类的功能,会导致子类无法替换父类,导致引用出现异常)。
个人理解的话,更像是因为假如子类篡改了父类的功能,会导致在多态的时候父类无法成功地指向子类最终引起程序的功能瘫痪。
里氏替换原则是开闭原则的补充,实现开闭原则的关键就是抽象化,而基类与子类的继承关系就是抽象化的具体体现。里氏原则是对实现抽象化的具体规范。
在进行设计时,我们应该尽量从抽象类继承,而不是从具体类继承。如果从继承树上来看,所有的叶子节点都应该是具体类,而所有的树枝节点应该是抽象类或者接口。
感觉里氏替换原则在框架中非常常见,看过Spring的一点源码跟源码解析,其中Spring容器的继承树就非常符合里氏替换原则(当然也很符合其他的设计原则,比如单一功能原则之类的)。
依赖倒置原则:
定义:高层模块不应该依赖低层模块。两个都应该依赖抽象;抽象不应该依赖细节,细节应该依赖抽象;(针对接口编程,而不是针对实现;)
我感觉这个好像没什么需要太分析的吧?
抽象(接口)应该是一切模块的依赖起源。具体的实现(细节),应该依赖于接口(抽象)而存在。
通过抽象来规范业务方向,然后通过细节来实现抽象,当实际需求发生变化的时候,可以直接修改细节来实现而不需要对抽象进行修改(当然你的抽象得考虑周全,不过也可以利用接口的多实现来弥补这个问题。果然规则制定者是最厉害的啊)。
接口隔离原则/合成聚合原则:
定义:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。
个人感觉这就像是避免出现规模庞大的接口,可以将复杂的功能分散到多个接口中,最终通过多实现了灵活性与复用性。
(假如你们源接口功能庞大,你要实现的功能位于其中,但是你只是想实现其部分功能,那多余的功能对于你来说是不是像鸡肋一样,不可不实现,但是实现了也是空白。食之无味,弃之可惜啊)
注意情况:
- 接口尽量小,但是要有限度。对接口进行细化可以提高程序设计灵活性是不挣的事实,但是如果过小,则会造成接口数量过多,使设计复杂化。所以一定要适度。
- 为依赖接口的类定制服务,只暴露给调用的类它需要的方法,它不需要的方法则隐藏起来。只有专注地为一个模块提供定制服务,才能建立最小的依赖关系。
- 提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。
感觉这些设计模式的原则,不仅仅是对设计模式有用,实际对于项目的开发也很有用,如果项目开发时能遵循这些原则,那么后续维护和升级就会相对简单很多。或者说代码的可读性什么的都能得到很好的继承和维护。但是一旦你设计出了问题,在后续的开发过程中可能需要你用别的方法来解决,最终导致出现莫名其妙的bug,导致后期维护难度增大。
果然应该多看多想,形成思路之后再往后走。
迪米特法则:
定义1:一个对象应该对其他对象保持最少的了解。
定义2:如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用,如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。
核心思想是:类之间的松耦合(不管对于什么项目来说,你中有我我中有你都不是一个很好的现象。也是这几个原则看到现在的感受,无时无刻不在提示,不要造成相互纠缠,或者说降低耦合性)。
实质是尽量避免出现类作为成员变量存在。(感觉这样又有点跟面向接口编程有冲突,不过应该不算冲突的意思吧。反正目前在我看来是有点这么个意思)。
开闭原则:
定义:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。
对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。
对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对类进行任何修改。
这样做,面对需求变化,通过扩展来实现新需求,可以使整个程序从第一个版本开始就有很好的功能性(第一版设计完成实现之后就能满足其业务需要)跟拓展性(面对新需求新需要,可以通过拓展功能来实现。)
(但是根据上面括号的内容想来,程序的体谅会越来越大越来越难以维护,就目前看我感觉这是所有程序的最终宿命)。
上述就是六大原则跟我对这些原则的理解。鉴于学习过程的局限性,或者说知识体系的局限性,可能还有很多问题。如果有朋友看到可以放心大胆地指出。
我很欢迎批评,也很乐于接受批评,也很愿意跟各位在交流中相互学习。
期待你的到来
java中的设计模式及其六大原则的更多相关文章
- Java 设计模式(二)-六大原则
Java 设计模式(二)-六大原则 单一职责原则(Single Responsibility Principle) 定义: 不要存在多余一个原因导致类变更,既一个类只负责一项职责. 问题由来: 当类A ...
- C#之设计模式之六大原则(转载)
设计模式之六大原则(转载) 关于设计模式的六大设计原则的资料网上很多,但是很多地方解释地都太过于笼统化,我也找了很多资料来看,发现CSDN上有几篇关于设计模式的六大原则讲述的比较通俗易懂,因此转载过来 ...
- 设计模式之六大原则——接口隔离原则(ISP)
设计模式之六大原则——接口隔离原则(ISP) 转载于:http://www.cnblogs.com/muzongyan/archive/2010/08/04/1792528.html 接口隔离原则 ...
- Java中单态设计模式
Java中单态设计模式 2011-09-23 16:38:46| 分类: Java | 标签:technology! |举报|字号 订阅 此博文是转自新浪博客中一名叫做"俊俊的 ...
- 0 Java实现 一篇文章说尽设计模式之六大原则
我们知道,设计模式很有用,学好设计模式不但能让你写出更简洁,优雅的代码,还能使得代码的结构更清晰,也更有利于扩展 当然设计模式也不是万能的,一成不变的.设计模式只是前人总结出来的一种经验,一种特定问题 ...
- Java中常见设计模式面试
一.设计模式的分类 总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接 ...
- .NET 设计模式的六大原则理论知识
1. 单一职责原则(SRP)(Single Responsibility Principle)2. 里氏替换原则(LSP)(Liskov Substitution Principle)3. 依赖倒置原 ...
- C#之设计模式之六大原则
一.单一职责原则 原文链接:http://blog.csdn.net/lovelion/article/details/7536542 单一职责原则是最简单的面向对象设计原则,它用于控制类的粒度大小. ...
- Java中的设计模式之单例模式
Java中的单例模式 设计模式是软件开发过程中经验的积累 一.单例模式 1.单例模式是一种常用的软件设计模式,通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控 ...
随机推荐
- EF之POCO应用系列3——延迟加载
EF之POCO应用系列4——延迟加载 当我们进行查询的时候,哪些关系的数据将会被加载到内存呢?所有相关的对象都需要吗?在一些场合可能有意义,例如,当查询的实体仅仅拥有一个相关的子实体,但是,多数情况下 ...
- python(pytest)+allure+jenkins 实现接口自动化的思路
效果图镇楼: 上述各模块作用: python(pytest): 1:用于读测试用例(本次用例写在csv文件中) 2:环境配置相关 3:提取1中的测试数据,组成请求体 4:发送请求 5:获取结果 6:断 ...
- Django 之 ORM 字段和字段参数
ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描述 ...
- python基础17 ---继承补充知识
一.继承的顺序 1.在python中的类可以集成多个类,既然是继承多个类就有类的寻找顺序这么一说.其寻找方法就有广度优先和深度优先两种. 2.当类是新式类,多继承的情况下会按照广度优先的顺序查找. 如 ...
- 小程序连接百度ai
function getTextFromImage(res) { var access_token = '24.c649256d2e*****0.282335-11449805'; var url = ...
- rails常用函数
1.rails g controller Users rails g model User 2.user.reload.email reload 使用数据库中的数据重新加载对象
- iOS 图文混排 链接 可点击
对于这个话题 我想到 1 第一个解决方法就是使用 webView 比较经典 把所有复杂工作都交给控件本身去处理了, 但是好像好多需要自定义的地方 没法从 webView获得响应回调 :(估计也可以实 ...
- c++之默认参数的函数
默认参数,看个例子就明白了 int add(int a=5,int b=6,z=3): int main(){ add():// 全部默认 add(1,5)://第三个参数默认 add(1,2,3): ...
- Data Structure Linked List: Write a function to get the intersection point of two Linked Lists.
http://www.geeksforgeeks.org/write-a-function-to-get-the-intersection-point-of-two-linked-lists/ 第一第 ...
- nodejs模块之fs&&stream
nodejs的文件系统fs模块,可以实现对文件.目录等的操作,stream模块实现对文件数据的断续读写操作 一.文件操作 fs.readFile(file[,options],callback) 异步 ...