悟空模式-java设计模式
目前已定义的java设计模式细分下来有二十余种,这篇博客主要是想从大家所熟知的孙悟空入手,阐述各个设计模式的概念和优缺点,以及他们之间的联系。
在下面介绍的每个设计模式里,都会有与西游记相关的具体案例,主要是为了方便大家理解与记忆,否则使用一些枯燥的例子,很难让人印象深刻。
在很多设计模式相关的书籍与博客中都有与孙悟空相关的代码案例,在这里,会结合《西游记》原文,尽量使用更加贴切的事例进行描述,如果你觉得所举事例不太适合,或者有更好的想法,欢迎在评论区中指出。
按笔者的理解,设计模式的作用无非是让代码解耦合、易扩展、设计清晰以及体现封装,当真正理解了设计模式的理念之后,就可以达到随意组合使用设计模式,或者在不参照具体的设计模式模板的情况下又能体现设计模式内在理念的高度,希望这个博客对大家有所帮助。
下面是各个设计模式的详细链接(暂无实际跳转的会陆续更新):
悟空模式-java-适配器模式
悟空模式-java-装饰器模式
悟空模式-java-代理模式
悟空模式-java-外观模式
悟空模式-java-桥接模式
悟空模式-java-享元模式
悟空模式-java-策略模式
悟空模式-java-模板模式
悟空模式-java-观察者模式
悟空模式-java-迭代子模式
悟空模式-java-责任链模式
悟空模式-java-命令模式
悟空模式-java-访问者模式
悟空模式-java-状态模式
悟空模式-java-中介者模式
悟空模式-java-解释器模式
悟空模式-java-备忘录模式
悟空模式-java-不变模式
悟空模式-java-合成模式
这里介绍一下Java的六大基本设计原则:
1.单一职责原则
一个类只负责一件事情,尽量不要让一个类因为多种原因(业务变更)需要发生改变,也尽量不要让一个类变得太复杂。
比如孙悟空就负责打妖怪,沙僧就负责扛行李,白龙马就负责背着唐僧,这样是单一职责。要是让白龙马又负责背唐僧,又负责驮行李,还要负责打妖怪,白龙马就崩溃了,搞不好没几天就回鹰愁涧了。你可以把单一职责原则理解为白龙马只背唐僧原则。
2.里氏替换原则
任何父类可以出现的地方,子类也一定可以出现,将父类替换为子类对程序没有影响。子类可以实现父类的抽象方法,但不要重写父类的非抽象方法。子类可以增加自己新的行为,但不要覆盖父类已经实现的方法。当子类的方法重载父类的方法时,方法的前提条件(即方法的参数)要比父类方法的输入参数更宽松;当子类的方法实现父类的抽象方法时,方法的后续条件(即方法的返回值)要比父类更严格。因为当调用父类的方法时,用户只知道父类的前提条件和后续条件。
比如有一个父类叫唐僧徒弟,那么孙悟空可以继承这个类。系统中,所有用到唐僧徒弟类的地方,它的具体实现被替换为孙悟空或者猪八戒都不会影响到程序的正常执行。系统允许孙悟空和猪八戒有自己独特的行为,但父类唐僧徒弟中已经实现的方法,尽量不要去重写,否则可能会影响调用者的认知,因为调用者只知道获取的对象是唐僧徒弟,所以它只对预期中唐僧徒弟的行为做了处理,一旦方法被重写,可能会产生问题。比如唐僧对于徒弟,当徒弟不听话的时候,就调用“紧箍咒”方法,唐僧徒弟类会执行相应的“听到紧箍咒”方法,变得“听话”。可万一某个徒弟(肯定是孙悟空了)悄悄地把“听到紧箍咒”方法给重写了,就会导致代码不能按唐僧的预期正常运行,唐僧搞不清楚为什么对徒弟念紧箍咒,徒弟却还是不听话。你可以把里氏替换原则理解为紧箍咒必须有效原则。
3.依赖倒置原则
高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。即针对接口编程而不针对实现编程,面向抽象编程而不面向细节编程。
比如孙悟空有七十二变,时而变成鸟,时而变成鱼,有时又变成小和尚。如果我们依赖具体的实现进行编程的话,那么七十二变后孙悟空移动的方法就会写成下面这样:
public static void move(){
if(Bird){
fly;
}else if(Fish){
swim;
}else if(Human){
walk;
}else if(...){
...
}
}
这样会非常难以维护和调整,也非常难以阅读。但如果我们依赖抽象编程的话,可以把鸟、鱼、小和尚等等都抽象成孙悟空的一种变化,然后每个变化都实现一个move的方法,当我们调用孙悟空七十二变后的移动方法时,系统就会自动根据孙悟空当前的变化类型调用对应的move方法,这样就将依赖分离开了,上层代码只要依赖七十二变的抽象进行编程,而不需要依赖七十二变的具体实现形式。你可以把依赖倒置原则理解为七十二变原则。
4.接口隔离原则
一个类对另一个类的依赖应该建立在最小的接口上,客户端不应该依赖它不需要的接口。
这个原则理解起来可能很容易和单一职责原则产生混淆。我们要知道的是,单一职责原则针对的是程序的实现和细节,注重的是职责,而接口隔离原则注重的是隔离,针对的是整体框架的构建。
比如唐僧的几个徒弟各有各的特点,各有各的职责,如果让他们都依赖同一个接口,就会出现孙悟空也要实现背行李方法,白龙马也要实现打妖怪方法的情况,尽管孙悟空从来不背行李,也基本上从来轮不到白龙马打妖怪,这就造成接口非常臃肿。所以接口中的方法应该尽量少,我们可以将各个徒弟的职责抽象为战斗类、生活类等各个独立的接口,徒弟们只要实现自己必须要实现的接口就可以了,这样依赖多个专用的接口会比依赖一个综合的接口灵活的多。你可以把接口隔离原则理解为白龙马不打妖怪原则。
5.最少知道原则(迪米特法则)
一个类对自己依赖的类知道的越少越好。作为一个被依赖的类,应该尽可能将自己的实现细节保留在内部,除了提供必需的接口,不泄露任何不必要的信息。
比如孙悟空经常要打妖怪,但是唐僧总是干预孙悟空打妖怪的细节,非要说孙悟空打错了,这就是因为作为一个被依赖的类,孙悟空没有把自己的打妖怪逻辑严密地封装起来,导致依赖他的唐僧可以干预他执行打妖怪的方法,但实际上他并不需要唐僧告诉他怎么打妖怪。如果唐僧能够遵循最少知道原则,对自己不能完全了解的孙悟空打妖怪逻辑不进行干预的话,西游路上将会少去很多麻烦,因为你往往并不能充分了解自己依赖的类内部的实现逻辑,也往往无法做到正确的干预。你可以将最少知道原则理解为唐僧指挥悟空打妖怪原则。
6.开闭原则
一个软件实体,如类、模块、方法,应当对扩展开放,对修改关闭。通俗的说,就是尽量通过扩展实体的行为来实现变化,而不是通过修改已有的代码来实现变化。
比如孙悟空从自由自在的齐天大圣变成了苦苦取经的孙行者,当我们要调整孙悟空的一些行为模式的时候,尽量不要修改齐天大圣的实现代码,可以考虑增加孙行者的接口,让孙悟空实现这个新的接口,然后增加孙行者的行为。这样能够防止一些旧的代码中使用了齐天大圣代码,修改后可能出现错误,也能够避免日后取经结束,孙悟空又变回了齐天大圣,又要修改回原来的代码,增加工作量不说,也不一定能够完全还原齐天大圣的全貌。你可以将开闭原则理解为齐天大圣孙行者原则。
正所谓无招胜有招,用不用、用哪个设计模式其实并不用刻意为之,只要能够深刻体现以上这些设计原则的精神,使得代码能够更方便更合理地适应业务变化的方向,你就会发现,自然而然就使用了一个或多个设计模式。
悟空模式-java设计模式的更多相关文章
- 装饰者模式——Java设计模式
装饰模式 1.概念 动态地为对象附加上额外的职责 其目的是包装一个对象,从而可以在运行时动态添加新的职责.每个装饰器都可以包装另一个装饰器,这样理论上来说可以对目标对象进行无限次的装饰. 2.装饰器类 ...
- 工厂模式——java设计模式
工厂模式 目录 何为工厂模式 工厂方法与抽象工厂 如何在Java EE中通过@Producers与@Inject注解实现工厂模式 如何创建自定义注解以及通过@Qualifier消除具体实现之间的歧义 ...
- 代理模式——java设计模式
代理模式(Proxy Pattern) GoF中给出的代理模式的定义为: 代理模式给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问. 代理模式的英文叫做Proxy或Surrogate ...
- 生产者和消费者模式--java设计模式
生产者和消费者: 就犹如在快餐店点餐一样,有多个打饭的,有不定时的人来买饭,买饭的人从快餐店自动取餐,如果快餐的库存数量达到下限值时,自动启动打饭的,补充盒饭. 通过while循环的方式,传入变量is ...
- 悟空模式-java-建造者模式
[此是锻炼神冰铁,磨琢成工光皎洁.老君自己动钤锤,荧惑亲身添炭屑.五方五帝用心机,六丁六甲费周折.造成九齿玉垂牙,铸就双环金坠叶.身妆六曜排五星,体按四时依八节.短长上下定乾坤,左右阴阳分日月.六爻神 ...
- 悟空模式-java-原型模式
[却说那妖精与大圣斗经半日,不分胜败.行者把棒丢起,叫一声“变!”就以一变十,以十变百,以百变千,半天里,好似蛇游蟒搅,乱打妖邪.妖邪慌了手脚,将身一闪,化道清风,即奔碧空之上逃走.行者念声咒语,将铁 ...
- 悟空模式-java-单例模式
[那座山,正当顶上,有一块仙石.其石有三丈六尺五寸高,有二丈四尺围圆.三丈六尺五寸高,按周天三百六十五度:二丈四尺围圆,按政历二十四气.上有九窍八孔,按九宫八卦.四面更无树木遮阴,左右倒有芝兰相衬.盖 ...
- 悟空模式-java-抽象工厂模式
[一朝,王母娘娘设宴,大开宝阁,瑶池中做蟠桃胜会] 有一天,王母娘娘要在瑶池办party,就需要准备大量的食材.要知道,天上的神仙也分三六九等,九曜星.五方将.二十八宿.四大天王.十二元辰.五方五老. ...
- 悟空模式-java-工厂方法模式
[却说那七衣仙女自受了大圣的定身法术,一周天方能解脱,各提花篮,回奏王母说道:“齐天大圣使术法困住我等,故此来迟.”王母问道:“汝等摘了多少蟠桃?”仙女道:“只有两篮小桃,三篮中桃.至后面,大桃半个也 ...
随机推荐
- flask之信号
Flask框架中的信号基于blinker,其主要就是让开发者可是在flask请求过程中定制一些用户行为. pip3 install blinker 1. 内置信号 request_started = ...
- $_SERVER[]数组解析
$_SERVER['PHP_SELF'] 将会得到 /test.php/foo.bar 这个结果.__FILE__ 常量包含当前(例如包含)文件的绝对路径和文件名. 如果 PHP 以命令行方式运行,该 ...
- 详解linux下的串口通讯开发
串行口是计算机一种常用的接口,具有连接线少,通讯简单,得到广泛的使用.常用的串口是RS-232-C接口(又称EIA RS-232-C)它是在1970年由美国电子工业协会(EIA)联合贝尔系统.调制解调 ...
- nodejs实现请求代理
通常我们常用的请求方法只有GET.POST.PUT和DELETE,所以在此只介绍这四种和文件上传的代理方式 在此我们使用request.js第三方模块实现 GET(DELETE同GET,将reques ...
- 面向 B 端的产品经理
简评:越来越多人涌入产品经理这个岗位,但是面对不同的产品和客户群体,产品经理所需要的技能.知识和经验可能大相庭径. 近几年随着移动互联网的爆发性增长,几乎遍地都是产品经理了.华尔街日报 也曾报道称「产 ...
- UITableView 的常用可复制代码
UITableView是使用中最常用的工具,下面列举一个常用的tableview类,以后直接复制代码,稍作修改,就能用了. #import "ViewController.h" @ ...
- hbase搭建web项目 报500错误 HTTP Status 500 - Unable to compile class for JSP
在昨天,用hbase做后台搭建web项目时,前边的进行的非常顺利,当运行时便 报错了,截图如下: 这是直接在jsp中接收参数报的错误,如果在servlet中,同样也是报500的错误,虽然显示的不太一样 ...
- WebAPI Post接收数据
近日在写某开源商城的webapi接口,由于刚接触所以碰到某些问题,如post数据的接收啊等.在网上查询资料时给出了三种方式. 1.给多个数据对象封装成一个对象进行接收([frombody]标签只能用于 ...
- 手把手教你如何安装和使用Karma-Jasmine
注意:本文中出现的资料链接.karma的插件安装等,均可能需要翻$墙后才能正确执行. Jasmine是一个Javascript的测试工具,在Karma上运行Jasmine可完成Javascript的自 ...
- 12、xamarin form中实现H5 网页唤醒微信支付的方法
在微信的支付中有种支付叫微信H5支付.方便用户在网页中轻松唤起微信进行支付. 当然微信不推荐大家使用这样的方式唤起微信支付.建议app还是使用正常的微信支付sdk即可 服务端与其他的建议参考微信支付官 ...