悟空模式-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-工厂方法模式
[却说那七衣仙女自受了大圣的定身法术,一周天方能解脱,各提花篮,回奏王母说道:“齐天大圣使术法困住我等,故此来迟.”王母问道:“汝等摘了多少蟠桃?”仙女道:“只有两篮小桃,三篮中桃.至后面,大桃半个也 ...
随机推荐
- IAP远程在线升级
IAP远程在线升级 在上一篇中实现了LWIP网口通讯,那么肯定要加个在线升级功能,这个功能所占用的资源很少,但在物联网中很重要也很实用.在线升级就是像手机一样,先下载好系统,然后点击升级~然后就没然后 ...
- 图片后门恶意捆绑工具FackImageexploer
本文作者:夜莺 今天向大家提个醒,最近有一款工具名叫FackImageexploer,该工具能够将恶意的.bat和.exe程序与图片绑定在一起,假若受害者点击了图片,就会反弹个shell给不法分子,如 ...
- 应该怎么理解 app = Flask(__name__)
初始化生成一个app对象,这个对象就是Flask的当前实例对象,后面的各个方法调用都是这个实例Flask会进行一系列自己的初始化,比如web API路径初始化,web资源加载,日志模块创建等.然后返回 ...
- php-echo原理
1.语法分析 unticked_statement: | T_ECHO echo_expr_list ';' ; echo_expr_list: echo_expr_list TSRMLS_CC); ...
- System.Thread.TImer控件——http://www.360doc.com/content/11/0812/11/1039473_139824496.shtml
http://www.360doc.com/content/11/0812/11/1039473_139824496.shtml
- Java模拟双色球彩票
package practice1; import java.util.Random; import java.util.Scanner; public class Test3 { /** * * 模 ...
- python-在定义函数时,不定长参数中,默认值参数不能放在必选参数前面
如果一个函数的参数中含有默认参数,则这个默认参数后的所有参数都必须是默认参数,否则会报错:SyntaxError: non-default argument follows default argum ...
- 搭建互联网架构学习--005--框架初步拆分ssm单一框架
经过前边的准备步骤,服务器基本搭建完毕,接下来就开始一步步搭建框架了. 拆分单一结构:拆分的目的是为下一步引入dubbo做准备的. 把下边这个单一maven框架进行拆分 这个就是一个简单的maven项 ...
- Vue中子组件调用父组件的方法
Vue中子组件调用父组件的方法 相关Html: <!DOCTYPE html> <html lang="en"> <head> <meta ...
- sql返回行id
1.sql语句中 insert into tableName() output inserted.id values() 2 .存储过程中 ALTER PROCEDURE dbo.getBuyMedi ...