读Android之大话设计模式--六种设计原则

设计原则一:针对接口编程,不针对实现编程

原文:http://www.cnblogs.com/guoshiandroid/archive/2010/06/07/1753270.html

定义: 

接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此 这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。

      接口是对抽象的抽象。

      接口就是标准,就是承诺。

      针对接口编程,不要针对具体编程是依赖倒转原则的另外一种表述。

      针对接口编程又称为面向接口编程,针对接口编程就是要先设计一系列的接口,把设计和实现分离开,使用时只需引用接口即可,也由于系统各部分的解耦合。如下图所示:

设计原则二:单一职责原则

原文:http://www.cnblogs.com/guoshiandroid/archive/2010/06/08/1754261.html

定义: 

单一职责原则(Single Responsibility Principle ):就一个类而言,应该仅有一个引起它变化的原因。换句话说,一个类的功能要单一,只做与它相关的事情。

如果一个完成额外的不太相关的功能或者完成其它类的功能,这就会使得一个引起一个类变化的因素太多,如果类的一处需要修改,其它和它相关连的代码都会受到影响,这就直接导致一旦系统出现了问题就难以调试困境,同时这样也非常不利于维护。

遵循单一职责原则也会给测试带来极大的方便。

违背单一职责原则会降低类的内聚性、增强类的耦合性。        

违背单一职责原则会导致错误呈现几何级数的增长,因为类之间的关联性太强,每一个类都会对其他类有影响,一个类出现错误极可能会导致其他相关联的类出现错误,而且关联类联合起来还有可能产生新的错误。

在软件开发中,人们越来越意识到单一职责原则的重要性,美工只需要负责美工界面,业务层的人员只需写好业务代码,而数据层的人员只需关注数据层的工作即可。这样每个人都以自己专程协同工作,工作效率就得到了大大的提高了。

现在软件开发的经典模式MVC模式,也非常好的体现了单一职责原则。MVC(Model-View-Control)就是模型、视图、控制器三层架构模式,其中M是指数据模型、V是指用户界面、C则是控制器。采用MVC模式使得数据和表现相分离,同一个数据层可以有不同的显示层。数据层和显示层的改变互不影响。这就非常有利于提高软件的可维护性和可复用性,同时也方便了软件的管理工作和提高软件开发效率。

如下图所示:

已有应用简介:我们这里已经以MVC模式为例来分析单一职责原则的应用。

      模型车、视图层、控制层各司其责、相互独立,一个模型可以有多个视图,一个视图可以有多个控制器,同样的一个控制器也可以由多个模型。MVC基本的处理流程如下: 用户与视图交互,视图接受并反馈用户的动作;视图把用户的请求传给相应的控制器,有控制器决定调用哪个模型,然后由模型调用相应的业务逻辑对用户的请求进行加工处理,如果需要返回数据,模型会把相应的数据返回给控制,由控制器调用相应的视图,最终由视图格式化和渲染返回的数据,以一种对用户尽可能友好的方式展现给用户。

设计原则三:开放封闭原则

原文:http://www.cnblogs.com/guoshiandroid/archive/2010/06/12/1756740.html

定义: 

开放封闭原则(Open-Closed Principle):一个软件实体应当对扩展开放,则修改关闭。对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况;对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对类进行任何修改。

开放封闭原则是所有面向对象原则的核心

“需求总是在变化”。

“世界没有一个软件是不变的”。

如何做到开放封闭原则呢?答案是:封装变化,依赖接口和抽象类,而不要依赖具体实现类。要针对接口和抽象类编程,不要针对具体实现编程。因为接口和抽象类是稳定的,他们是一种对客户端的一种承诺,是相对不变的。如果以后需要扩展或者开发新的功能,只需要实现或者继承接口或者抽象类即可覆盖或者扩展新的功能,这样做同时也不会影响新的功能。这就很好的做到了对扩展开放、对修改关闭。

实际上讲,绝对封闭的系统式不存在的。无论我们怎么保持封闭,一个系统总会有要变化的地方,“世界上没有一个不变的软件”、“需求总是在改变”。我们要做的不是消灭变化,而是把变化隔离开来,并对其进行封装。我们无法控制变化,但是我们可以预则哪里会发生变法。把要变化的地方抽象起来,这样以后再面临变化的时候我们就可以尽量的扩展,而无须改变以后的代码。

如下图所示:

已有应用简介: 

开放封闭原则是所有面向对象原则的核心。

软件的分析、设计、编码、维护等生命周期的各个阶段总是力求做到对修改关闭、对扩展开放。

著名的巴巴运动网生命周期的各个阶段就遵循了开放封闭原则。它把基本的CRUD操作做成了一个接口,同时采用了JDK 5引入的泛型技术,这样就可以保证以后做基本的添删改查操作时只需要实现该类即可。但由于引入了泛型技术,同时在后台提供了对接口的抽象实现,你甚至不用写一行代码,就可以自如的操作数据库。如果以后又需要扩展的地方,只需要扩展继承扩展自己的特有的操作即可,大大提高了生产效率。 

设计原则四:里氏代换原则

原文:http://www.cnblogs.com/guoshiandroid/archive/2010/06/14/1758047.html

定义:       

里氏代换原则(Liskov Substitution Principle)是指:一个软件实体如果使用的是基类的话,那么也一定适用于其子类,而且它根本觉察不出使用的是基类对象还是子类对象;反过来的代换这是不成立的,即:如果一个软件实体使用一个类的子类对象,那么它不能够适用于基类对象。

 里氏代换原则是由麻省理工学院(MIT)计算机科学实验室的Liskov女士,在1987年的OOPSLA大会上发表的一篇文章《Data Abstraction and Hierarchy》里面提出来的,主要阐述了有关继承的一些原则,也就是什么时候应该使用继承,什么时候不应该使用继承,以及其中的蕴涵的原理。2002年,软件工程大师Robert C. Martin,出版了一本《Agile Software DevelopmentPrinciples Patterns and Practices》,在文中他把里氏代换原则最终简化为一句话:“Subtypes must besubstitutable for their base types”。也就是,子类必须能够替换成它们的基类。

里氏代换原则讲的是基类和子类的关系,只有这种关系存在的时候里氏代换原则才能够成立。

里氏代换原则是实现开放封闭原则的具体规范。这是因为:实现开放封闭原则的关键是进行抽象,而继承关系又是抽象的一种具体实现,这样LSP就可以确保基类和子类关系的正确性,进而为实现开放封闭原则服务。

如下图所示:

已有应用简介: 

       这里主要分析一下Java编译器对里氏代换原则的支持机制。

       在Java中如果子类覆盖了基类的方法,子类中该方法的访问权限必须是不能低于它在父类中的访问权限的。这样在才能保证在客户端程序调用父类相应方法而需要使用子类的相应的方法代替时(调用父类的方法时需要使用子类相应的方法是普遍的),不会因为子类的方法降低了访问权限而导致客户端不能在继续调用。

温馨提示: 

       里氏代换原则是很多其它设计模式的基础。

       它和开放封闭原则的联系尤其紧密。违背了里氏代换原则就一定不符合开放封闭原则。

设计原则五:迪米特法则

原文:http://www.cnblogs.com/guoshiandroid/archive/2010/06/19/1760671.html

定义: 

迪米特法则(Law of Demeter,简写LoD )又叫做最少知识原则(LeastKnowledge Principle 简写LKP),也就是说,一个对象应当对其他对象尽可能少的了解,不和陌生人说话。

    迪米特法则最初是用来作为面向对象的系统设计风格的一种法则,于1987年秋天由lanholland在美国东北大学为一个叫做迪米特的项目设计提出的。被UML的创始者之一Booch等普及。后来,因为在经典著作《 The PragmaticProgrammer》阐述而广为人知。

狭义的迪米特法则是指:如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一类的某一个方法的话,可以通过第三者转发这个调用。

广义的迪米特法则是指:一个模块设计的好坏的一个重要标志就是该模块在多大程度上将自己的内部数据与实现的有关细节隐藏起来。

一个软件实体应当尽可能少的与其他实体发生相互作用。

每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。

迪米特法则的目的在于降低类与类之间的耦合。由于每个类尽量减少对其他类的依赖,因此,很容易使得系统的功能模块功能独立,使得相互间存在尽可能少的依赖关系。

在运用迪米特法则到系统的设计中时,要注意以下几点:

第一:在类的划分上,应当创建弱耦合的类,类与类之间的耦合越弱,就越有利于实现可复用的目标。

第二:在类的结构设计上,每个类都应该降低成员的访问权限。

第三:在类的设计上,只要有可能,一个类应当设计成不变的类。

第四:在对其他类的应用上,一个对象对其他类的对象的应用应该降到最低。

第五:尽量限制局部变量的有效范围。

但是过度使用迪米特法则,也会造成系统的不同模块之间的通信效率降低,使系统的不同模块之间不容易协调等缺点。同时,因为迪米特法则要求类与类之间尽量不直接通信,如果类之间需要通信就通过第三方转发的方式,这就直接导致了系统中存在大量的中介类,这些类存在的唯一原因是为了传递类与类之间的相互调用关系,这就毫无疑问的增加了系统的复杂度。解决这个问题的方式是:使用依赖倒转原则(通俗的讲就是要针对接口编程,不要针对具体编程),这样就可以使调用方和被调用方之间有了一个抽象层,被调用方在遵循抽象层的前提下就可以自由的变化,此时抽象层成了调用方的朋友。

如下图所示:

已有应用简介: 

       迪米特法则或者最少知识原则作为面向对象设计风格的一种法则,也是很多著名软件设计系统的指导原则,比如火星登陆软件系统、木星的欧罗巴卫星轨道飞船软件系统。

温馨提示: 

迪米特法则是一种面向对象系统设计风格的一种法则,尤其适合做大型复杂系统设计指导原则。但是也会造成系统的不同模块之间的通信效率降低,使系统的不同模块之间不容易协调等缺点。同时,因为迪米特法则要求类与类之间尽量不直接通信,如果类之间需要通信就通过第三方转发的方式,这就直接导致了系统中存在大量的中介类,这些类存在的唯一原因是为了传递类与类之间的相互调用关系,这就毫无疑问的增加了系统的复杂度。解决这个问题的方式是:使用依赖倒转原则(通俗的讲就是要针对接口编程,不要针对具体编程),这样就可以使调用方和被调用方之间有了一个抽象层,被调用方在遵循抽象层的前提下就可以自由的变化,此时抽象层成了调用方的朋友。

设计原则六:合成聚合复用原则

原文:http://www.cnblogs.com/guoshiandroid/archive/2010/06/21/1761626.html

定义: 

合成聚合复用原则(Composite Aggregate Reuse Principle,简称为CARP)经常又被人们称为合成复用原则(Composite Reuse Principle,简称为CRP).合成聚合复用原则是指在一个新的对象中使用原来已经存在的一些对象,使这些原来已经存在的对象称为新对象的一部分,新的对象通过向这些原来已经具有的对象委派相应的动作或者命令达到复用已有功能的目的。

合成复用原则跟简洁的表述是:要尽量使用合成和聚合,尽量不要使用继承。

聚合(Aggregation)是关联关系的一种,用来表示一种整体和部分的拥有关系。整体持有对部分的引用,可以调用部分的能够被访问的方法和属性等,当然这种访问往往是对接口和抽象类的访问。作为部分可以同时被多个新的对象引用,同时为多个新的对象提供服务。

合成(Composition)也是关联关系的一种,但合成是一种比聚合强得多的一种关联关系。在合成关系里面,部分和整体的生命周期是一样的。作为整体的新对象完全拥有对作为部分的支配权,包括负责和支配部分的创建和销毁等,即要负责作为部分的内存的分配和内存释放等。从这里也可以看出来,一个合成关系中的成员对象是不能和另外的一个合成关系共享的。

为何“要尽量使用合成和聚合,尽量不要使用继承”呢?这是因为:第一,继承复用破坏包装,它把超类的实现细节直接暴露给了子类,这违背了信息隐藏的原则;第二:如果超类发生了改变,那么子类也要发生相应的改变,这就直接导致了类与类之间的高耦合,不利于类的扩展、复用、维护等,也带来了系统僵硬和脆弱的设计。而使用合成和聚合的时候新对象和已有对象的交互往往是通过接口或者抽象类进行的,就可以很好的避免上面的不足,而且这也可以让每一个新的类专注于实现自己的任务,符合单一职责原则。

聚合关系的示意图如下所示:

聚合关系的示意图如下所示:

已有应用简介: 

       对于面向对象的软件系统而言,如何提高软件的可维护性和可复用性始终是一个核心问题。合成聚合复用原则的合理而充分的使用时非常有利于构建可维护、可复用、可扩展和灵活性好的软件系统。合成聚合复用原则作为一种构造优质系统的手段几乎可以应用到任何环境中去。对于已有的应用这里就不在赘述啦。

温馨提示: 

       合成聚合复用原则虽然几乎可以应用到任何环境中去,但是这个原则也有自己的缺点。因为此原则鼓励使用已有的类和对象来构建新的类的对象,这就导致了系统中会有很多的类和对象需要管理和维护,从而增加系统的复杂性。

       同时,也不是说在任何环境下使用合成聚合复用原则就是最好的,如果两个类之间在符合分类学的前提下有明显的“IS-A”的关系,而且基类能够抽象出子类的共有的属性和方法,而此时子类有能通过增加父类的属性和方法来扩展基类,那么此时使用继承将是一种更好的选择。

原文地址:https://www.cnblogs.com/wangziqiang/p/3582030.html