设计模式的原则和常用的模式

(友情提示:如果对于java的面向对象基础还不熟悉的程序员们可以先看看《Android 内功心法(番外)——写在设计模式前》,面对对象编程基础。这样,回头来看设计模式就更加能够容易理解。)

对编程稍稍深入了解一点的工程师来说,设计模式并不陌生。但设计模式的理解和运用每个层次的人有不同深度和广度的理解。

若想了解设计模式,那么就要先摸清它的原则和行为模式。
设计模式不针对哪种编程语言,而是针对编程思想。所以我把设计模式归为内功心法之中。

先来说说设计模式的原则(包括标准原则描述和自己理解的描述)。

1,开闭原则(Open Close Principle)

*对扩展开放,对修改关闭。
在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。
为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类。*

开,对所有的拓展、细化、优化操作开发。
闭,对原有逻辑的修改关闭。
开闭原则的目的就是保证原有逻辑的正常情况下添加新的逻辑。

举个栗子:一个工厂,开始做肥皂。后来为了拓展行业渠道,尝试做香皂。那么这个工厂就要遵守开闭原则。对新增做香皂的业务开放(新开一条生产链),对修改做肥皂的业务关闭(把肥皂尝试做成香皂)。要不然,香皂做不成,把肥皂也修改的不能正常盈利,岂不是搬石头砸了自己的脚。

2,里氏代换原则(Liskov Substitution Principle)

*它是面向对象设计的基本原则之一。
任何父类或者基类可以出现的地方,子类一定可以出现。
它是继承复用的基石。只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。
里氏代换原则是对“开-闭”原则的补充。
实现“开-闭”原则的关键步骤就是抽象化。
而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范*

里氏代换的原则很简单,就是一个儿子,你如果想去做你父亲做的事情,那么你必须学会你父亲会的所有技能。作为儿子,你可以去编程,会武术,学跳舞。但是前提是你父亲会的喝酒,抽烟,把妹你都要会。这样,作为儿子才能真正的接替父亲的位置。
程序中,任何一个父类或者基类的方法在其子类或者孙子类中都必须全部继承或者全部实现。这样当任何一个需要基类的地方都可以用其子类代替。这就是里氏代换的原则。

3、依赖倒转原则(Dependence Inversion Principle)

这个是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体。

这个空口说来也说不太清楚,还是举个栗子:一个机器要把很多种类的饮料分类,最笨的办法就是给机器输入命令“碳酸饮料:可乐,雪碧,芬达;牛奶类:蒙牛,光明,伊利。”这样,机器就会去一一对应的找饮料,找到了可乐,就把它丢在碳酸饮料类。这叫让机器依赖“具体”。让它知道什么是什么。
而依赖抽象,则是弄出很多的大盒子,每个盒子上都是标签,比如碳酸饮料,牛奶,咖啡什么的。
机器只需要将每个盒子那来归类。碳酸饮料的盒子就放在碳酸饮料类里面。这样,机器不用知道每种饮料是什么,机器只用知道面前的几个大盒子是什么该放在哪里就ok。盒子就是“抽象”的。盒子可以代表可乐,可以代表雪碧,可以代表芬达。所以,盒子就成了逻辑(机器)和具体(饮料)之间的抽象(盒子)了。
这样看来,的确减少了很多的工作量。

4、接口隔离原则(Interface Segregation Principle)

使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思。

标准解释还是不太清楚。我补充一下:接口隔离的意思是:不要一个类放一个他自己需要的接口,然后其他类去调用这个类的时候去使用这个接口。而是把所有的接口统一起来,这个类需要实现某个接口,直接调用接口类中的接口。另一个类需要使用某个接口,则就实例化接口类中的某个接口。
这就是把接口隔离在一个类中统一管理。让类与类之间没有联系,而让他们都去找接口。

现实中有个东西就很好的表明这一思想。活动扳手。扳手的卡口是可以活动的。就像把很多型号的卡口集中于一身。这样,不管是那个螺丝都能来找这个扳手,找到自己想要的卡口型号。这个扳手的卡口就相当于一个“接口”的统一管理类。而螺丝就是很多很多需要某个接口的“使用类”。而扳手则就是某个型号的“实现类”。卡口就成功的成了隔离众多接口的一个“接口统一管理类”

5、迪米特法则(最少知道原则)(Demeter Principle)

为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。

这个比较容易理解。程序中,最少知道原则的最好体现就是众多的utils工具类。某个工具类,你传入一个参数,就可以返回给你一个想要的结果。这就是最少知道原则的最好体现。当然,放在设计模式中比这个要稍微复杂一些,不过意思就是这样。

6、合成复用原则(Composite Reuse Principle)

*原则是尽量使用合成/聚合的方式,而不是使用继承。
组合和聚合都是对象建模中关联(Association)关系的一种.聚合表示整体与部分的关系,表示“含有”,整体由部分组合而成,部分可以脱离整体作为一个独立的个体存在。组合则是一种更强的聚合,部分组成整体,而且不可分割,部分不能脱离整体而单独存在。在合成关系中,部分和整体的生命周期一样,组合的新的对象完全支配其组成部分,包括他们的创建和销毁。一个合成关系中成分对象是不能与另外一个合成关系共享。*

这个理解起来用两个集体来表示最好不过。聚合就相当于一个班级。6年3班由40个同学组成,某个同学走了,6年3班还是6年3班,走的同学还是可以完成作为学生的一切行为。就算走了39个同学,意思还是一样。聚合由个体组成,但个体可以脱离聚合单独使用,聚合失去个体也可以存在。

而组合就相当于一个app软件开发团队。队伍中有销售,有后台,有android,有ios,还有经理。这是一个团队,是个“合成”。这个组合中任何一个成员离开都不能叫团队了,而离开的成员也不能单独完成任务。开发团队就是一个部分组成但不可分割的“合成”。
不管是聚合还是合成,其中的对象都不能和另外的聚合或者合成达成关系。就像,6年3班的同学不可能是6年4班的同学,这个开发团队的成员不可能同时为另一个团队工作。

另外:除了这几种原则之外,《大话设计模式》中还表述了:

单一原则

是这样描述的:就一个类而言应该只有一个引起它变化的原因。

好了,这就是设计模式的原则。只要深入了解了设计模式的原则, 自己就可以设计出很多优秀的设计模式。现在为止设计模式已经有很多种了,但是最经典的还是人人熟知的那24种。

那么,个人建议每一种都要学习,一一学习的机会就留给大家去完成了。我主要说说,android中经常用到的一些设计模式。

一般来说,常用的有以下八种:单例、工厂、观察者、代理、命令、适配器、合成、访问者。

单例模式:目的是为了让系统中只有一个调用对象,缺点是单例使其他程序过分依赖它,而且不同单例运行在不同进程中,使得维护困难;
这里不得不提到一点,一般的单例,刚刚开始接触设计模式的人会用synchronized来同步不同线程中的进入顺序。
虽然很直观很简单。但是,这种单例在序列化和反射机制的时候依然不能达到单例的效果。也就是说它能满足百分之九十的逻辑处理。只要你的程序不太复杂,那么用这种是完全没问题的。

那么问题来了。还有没有更好的办法?
其实早就不是什么新技巧了。枚举。
由于时间原因,以后会详细讲解。

工厂模式:生产固定的一些东西,如抽象类,缺点是产品修改麻烦;如喜欢动作片和爱情片的人分别向服务器发出同一个请求,就可以得到他们想看的影片集,相当于不同对象进行同一请求,需求均得到满足。
做过类似超市收银的应该都清楚,工厂模式在其中体现的最为贴切。最好是工厂+策略模式,同时使用。

观察者模式:就是多个对象对一个对象进行监控,如缓存;
观察者模式让我想起了一个小小的工具库“EventBus.jar”。
这个工具库就是规定方法名,发送请求后,所有被规定的方法名的方法都会接收到值,就相当于一个比较简化的观察者模式。
我在设计框架的时候经常用这个工具库去发送网络请求的返回值。因为网络请求在任何页面任何时候都要返回。所以观察者模式再适合不过了。

代理模式:自己的事交给别人去做,分别返回结果即可,如异步线程;

命令模式:调用对象与作用对象之间分离,由中间件来协调两者之间的工作,如控制器;

适配器模式:将一个接口变成用户所需要的接口,如baseadapter可以适配listview和spinner,因为它们有相同的接口

合成模式:将一对多的关系转换成一对整体的关系,如listview与适配器;

访问者模式:对不同的对象采取不同的处理,如instanceof。

由于今天时间关系,先把这篇文章的目的写出来。 详解了设计模式的原则和几种android中常用的设计模式。 后续会给出每种设计模式的详细解释。

另外,推荐设计模式的书籍:
1,《大话设计模式》
简单易懂且有意思。(用c语言写的。不过相信接触设计模式的工程师们对于不同语言写的已经不是什么影响了)

2,《Android 源码设计模式解析与实战》
第一本关于android的设计模式。讲解android源码中用到的设计模式。设计模式用到最多的地方当然是源码了。

还有个超链接 http://mobile.51cto.com/android-419145.htm

希望对正在学习和准备进阶的工程师们有所帮助!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值