`
MyNameSky
  • 浏览: 28397 次
  • 性别: Icon_minigender_1
  • 来自: 永州
社区版块
存档分类
最新评论
阅读更多
面向对象的原则:

1.单一职责原则(SRP)
        RP说的其实是类设计时的职责划分和粒度问题。
        在软件开发中使用SRP原则时,一个类承担一个职责,过多互不相关的职责集中在一个类中会导致高耦合性。
        但要根据具体的情况设计,避免因过度追求单一职责而将类的结构设计的过度复杂,过犹不及。
        定义:
                每一个类应该只专注于做一件事
        解析:
                也可以理解为;只有有一个引起它变化的原因,如果一个类同时做两件事情,那么这两件事情都有可能引起它的变化。同样的道理,
                如果仅有一个引起它变化的原因,那么这个类也就只能做一件事情。这就是单一职责原则
        使用法则:
                单一职责原则把相同的职责进行聚合,避免把相同的职责分散到不同的类之中,这样就可以控制变化,把变化限制在一个地方,防止因为一个地方的变动,引起更多地方的变动的“涟漪效应”。单一职责原则实际上消除了对象之间的耦合,避免一个类承担过多的职责。单一职责不是说一个类就只有一个方法,而是单一功能 
        缺点:造成源文件增多,给管理带来不便,所以在实际应用中,可以对经常使用或经常需要改动的模块应用该原则,将其封装为独立的类。
        使用SRP注意点:
        1、一个合理的类,应该仅有一个引起它变化的原因,即单一职责;
        2、在没有变化征兆的情况下应用SRP或其他原则是不明智的;
        3、在需求实际发生变化时就应该应用SRP等原则来重构代码;
        4、使用测试驱动开发会迫使我们在设计出现臭味之前分离不合理代码;
        5、如果测试不能迫使职责分离,僵化性和脆弱性的臭味会变得很强烈,那就应该用Facade或Proxy模式对代码重构;
2.开放-封闭原则(OCP)
        定义:每一个类应该是对扩展开放(Open for extension),对修改关闭(Close for modification)
        解析:
                不修改原有代码即可完成对系统的扩展。
                开放-封闭原则的关键在于:抽象,也就是可变性的封装,抽象的目的是创建一个固定却能够描述一组任意个可能行为的基类。
                而这一组可能的行为则表现为该基类的子类。对于基类的更改是封闭的,所以它里边的方法一旦确定就不能更改(对接口里的方法进
                行更改将带来灾难性的后果)。模块通过抽象基类进行引用,所以子类的扩展并不影响整个模块,所以它是开放的
        使用法则:只对程序中频繁变化的部分进行抽象
        缺点:创建正确的抽象是要花费开发时间和精力的,同时抽象也增加了软件设计的复杂性
        使用OCP注意点:
                1、实现OCP原则的关键是抽象;
                2、两种安全的实现开闭原则的设计模式是:Strategy pattern(策略模式),
                        Template Methord(模版方法模式);
                3、依据开闭原则,我们尽量不要修改类,只扩展类,但在有些情况下会出现一些比较怪异的状况,这时可以采用几个类进行组合来完成;
                4、将可能发生变化的部分封装成一个对象,如: 状态, 消息,,算法,数据结构等等,封装变化是实现"开闭原则"的一个重要手段,如经常发生变化的状态值,如温度,气压,颜色,积分,排名等等,可以将这些作为独立的属性,如果参数之间有关系,有必要进行抽象。对于行为,如果是基本不变的,则可以直接作为对象的方法,否则考虑抽象或者封装这些行为;
                5、在许多方面,OCP是面向对象设计的核心所在。遵循这个原则可带来面向对象技术所声称的巨大好处灵活性、可重用性以及可维护性)。然而,对于应用程序的每个部分都肆意地进行抽象并不是一个好主意。应该仅仅对程序中呈现出频繁变化的那部分作出抽象。拒绝不成熟的抽象和抽象本身一样重要;
3.里氏(Liskov)替换原则(LSP)
        定义:任何基类可以出现的地方,子类一定可以出现,
        解析:所有的父类类型的对象都替换为子类类型时,程序的行为没有变化,反过来就不成立,如果一个软件实体使用的是子类类型的话,那么它不一定适用于基类
        LSP优点:
                1、保证系统或子系统有良好的扩展性。只有子类能够完全替换父类,才能保证系统或子系统在运行期内识别子类就可以了,因而使得系统或子系统有了良好的扩展性。
                2、实现运行期内绑定,即保证了面向对象多态性的顺利进行。这节省了大量的代码重复或冗余。避免了类似instanceof这样的语句,或者getClass()这样的语句,这些语句是面向对象所忌讳的。
                3、有利于实现契约式编程。契约式编程有利于系统的分析和设计,指我们在分析和设计的时候,定义好系统的接口,然后再编码的时候实现这些接口即可。在父类里定义好子类需要实现的功能,而子类只要实现这些功能即可。
          使用LSP注意点:
                1、此原则和OCP的作用有点类似,其实这些面向对象的基本原则就2条:
                        (1)面向接口编程,而不是面向实现;
                        (2)用组合而不主张用继承
                2、LSP是保证OCP的重要原则
                3、这些基本的原则在实现方法上也有个共同层次,就是使用中间接口层,以此来达到类对象的低偶合,也就是抽象偶合!
                4、派生类的退化函数:派生类的某些函数退化(变得没有用处),Base的使用者不知道不能调用f,会导致替换违规。在派生类中存在退化函数并不总是表示违反了LSP,但是当存在这种情况时,应该引起注意。
                5、从派生类抛出异常:如果在派生类的方法中添加了其基类不会抛出的异常。如果基类的使用者不期望这些异常,那么把他们添加到派生类的方法中就可以能会导致不可替换性。
        附A:
        基于契约设计(DBC:Design By Contract)
                使用DBC,类的编写者能够显式的规定针对该类的契约。客户代码的编写者可以通过该契约获悉可以依赖的行为方式。
                契约是通过为每个方法声明的前置条件(preconditions)和后置条件(postconditions)来指定的。
                要使一个方法得以执行,前置条件必须要为真。执行完毕后,该方法要保证后置条件为真。
        附B:
        use-a 依赖  A与B use-a关系   A中持有B的实例,B实例是在A之外创建,通过传参被A使用,可以调用B的方法或属性。
                例如:我使用电脑。
        has-a 组合  A与B has-a关系   A持有B的实例,A负责B的创建。
                1.静态Has-A关系。这在UML中叫做组合(composition)
                        例如:我有一双手
                2.动态Has-A关系。这在UML中叫做聚合(aggregation)
                        例如:Ant-Team拥有5名成员。
        is-a  继承  A与B is-a 关系    B是A的父类
4.依赖倒置原则(DIP)
        定义:依赖倒转原则就是要依赖于抽象,不要依赖于细节。要针对接口编程,不要针对实现编程对程序中频繁变化的部分进行依赖倒置。
        解析:应当使用高层的接口和抽象类作为变量的声明类型、参数的声明类型, 方法的返还类型声明,以及数据类型的转换等
        缺点:因为依赖倒转的缘故,对象的创建很可能要使用对象工厂,以避免对具体类的直接引用,此原则的使用将导致大量的类文件。给维护带来不必要的麻烦
5.接口隔离原则(ISP):
        描述:不要强迫客户依赖于它们不用的方法。
        应用:一个类对另外一个类的依赖性应当是建立在最小的接口上的。如果客户端只需要某一些方法的话,那么就应当向客户端提供这些需要的方法,而不要提供不需要的方法。提供接口意味着向客户端作出承诺,过多的承诺会给系统的维护造成不必要的负担。
        结论:使用多个专门的接口比使用单一的接口要好。
        其中:适配器模式是接口隔离原则的一个应用。
6.迪米特法则(Law of Demeter):
        又叫最少知识原则,一个对象应当对其他对象有尽可能少的了解。或者说是不和陌生人说话。
                好处是:提高内聚、降低耦合。
                缺点是:在系统里造出大量的小方法,这些方法仅仅是传递间接的调用,与系统的商务逻辑无关,还能造成系统的不同模块之间的的通信效率,使这些模块不容易协调。门面模式和调停者模式实际上就是迪米特法则的应用。
        用迪米特法则到系统的设计中时,要注意以下几点:
        * 在类的划分上,应当创建有弱耦合的类.类之间的耦合越弱,就越有利于复用.
        * 在类的结构设计上,每一个类都应当尽量降低成员的访问权限.
        * 在类的设计上,只要可能,一个类应当设计成不变类.
        * 在对其他类的引用上,一个对象对其他对象的引用应降到最低.
        * 尽量限制局部变量的有效范围.
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics