潇's profile老肖的地盘PhotosBlogListsMore Tools Help

Blog


    March 22

    原则,你懂不

    最近看了《疯狂的赛车》,里面那两个杀手,抑或是贼,也许又是毒贩,或者说他们是全才,反正他们的台词相当搞笑,“干一行爱一行”,“多行不义必自毙”,“不专业啊”,其中还有一句话就是“原则,你懂不”。

    其实我不怎么懂原则,我说的原则是软件设计中的原则,每次当我问那些有经验的前辈们,怎么设计才算是一个合理的设计方案,一般都会得到的回答就是,经验,当经历的项目多了,自然就会有一套自己设计的套路。这种回答也实在是无可奈何,毕竟软件设计没有一套验证合理性的数学模型,所以对于一个设计方案,我遇到很多设计评审就是,合理就可以,但没有人可以肯定,这个设计不会造成一些后果。尤其是对于我这种菜鸟来说,设计一个模块都让我战战兢兢,如履薄冰。所以嘛,不知道点原则,那么做出来的事情肯定就不专业了。虽然现在的经验不能保证我能够吃透这些原则,但完全不知道原则,那就像是拿着菜刀去和鬼子搏斗一般,也许一转身,发现还有AK47,迫击炮,火箭筒之类的,虽然现在不会用,但也得学,虽说有时候杀鸡用牛刀,偏偏用牛刀可以把鸡杀了,但反过来杀牛用鸡刀,只怕是牛占据格斗的优势。

    废话到此,先看伟大的wiki上对软件设计7条原则的描述:

    1.开闭原则(Open/closed principle)

    这个是最常提到的,当年我面试的时候,也被问过这个问题,简单的说,就是在面向对象的编程中,软件实体应该可以自由扩展,而不能被修改(software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification),也就是说,在要增加软件的功能,或者是要做其它方面的改进时,不能对原有的代码进行改动,而只能在原来的代码上进行添加。如果说你不得不修改原有的代码来改进一个模块的某些功能,那么只能说这个模块设计得不合理。

    2.里氏代换原则(Liskov Substitution Principle,常缩写为.LSP)

    这条原则是继承复用的基石。(Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T.)如果q(x)是对象x的属性,属于T类型,那么如果q(y)是y对象的属性,属于类型S,且S是T的子类型。换言之,一个软件实体如果是用的一个基类的话,那么一定适用于其子类,但是反之不然,基类无法完成子类的某些功能。

    由这条原则引申出了“基于契约设计”(Design By Constarct):类的编写者显式地规定针对该类的契约。客户代码的编写者可以通过该契约获悉可以依赖的行为方式。契约是通过每个方法声明的前置条件 (preconditions)和后置条件(postconditions)来指定的。要使一个方法得以执行,前置条件必须为真。执行完毕后,该方法要保证后置条件为真.就是说,在重新声明派生类中的例程(routine)时,只能使用相等或者更弱的前置条件来替换原始的前置条件,只能使用相等或者更强的后置条件来替换原始的后置条件。

    3.依赖倒置原则(Dependence Inversion Principle)

    这个原则也叫做控制翻转(Inverse of Control),该原则寻求颠覆传统看法,软件的高级模块应该依赖于软件的低级模块,取而代之的,软件的的高级和低级模块都应该依赖于公共的抽象。

    此条原则的有点在于,在软件开发中,开发者不需要在开发高级模块之前完成低级模块的开发,这就使得自顶向下的模式在设计和开发中都成为可能。

    具体而言,此条原则对我来说还很模糊,也许从Springs框架中的IOC,以及依赖注入可以体会到一些灵感。

    4.接口隔离原则(Interface Segregation Principle, ISP)

    一个类对另外一个类的依赖是建立在最小的接口上。

    多个专门的接口比使用一个单一的总接口好,可以根据客户程序的需要,配置不同的接口,而不需要千篇一律的使用大的总接口。

    也就是说,接口的粒度要尽可能的小……至于怎么小,具体情况具体分析了。

    5.合成/聚合复用原则(Composite/Aggregate Reuse Principle,CARP)

    在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分。新的对象通过这些向对象的委派达到复用已有功能的目的。这个设计原则有另一个简短的表述:要尽量使用合成/聚合,尽量不要使用继承。

    其实这个原则我总觉得有些霸王,通过继承也能完成复用,而且有的时候继承更加能反映真实世界的关系……也许有的时候,考虑到软件对象抽象和现实的映射关系,继承的抽象是不是更能够容易理解。等过一段时间,看下自己是不是对这条原则有新的认识。

    6.迪米特法则(Law of Demeter LoD)又叫做最少知识原则(Least Knowledge Principle,LKP)

    其基本观念是,对于给定的对象,他应该尽可能少的了解其它组件的结构和属性。就是说,两个类如果要发生通信,那么最好不要直接直接发生作用,可以通过第三者转发……

    其实这个理由很扯淡,通过第三者进行转发,那么不就是了解了第三者一些信息吗?抑或用一种特定的机制进行转发,搞不懂额。

    7.单一职责原则(Simple responsibility principle SRP)

    也就是说,一个类应该仅有一个引起它变化的原因,如果这个类有多个职责,那么就应该创建新的类去完成这些职责。

    恩~说了这些原则,不过很多原则还必须通过实际项目去加深理解,原则为何在设计中起着作用,以及原则和具体的设计模式直接有什么联系,我还要慢慢体会。如果不知道这些原则,那么就是做软件不专业……多行不义必自毙。(满嘴顺口溜,你考研啊)

    Comments

    Please wait...
    Sorry, the comment you entered is too long. Please shorten it.
    You didn't enter anything. Please try again.
    Sorry, we can't add your comment right now. Please try again later.
    To add a comment, you need permission from your parent. Ask for permission
    Your parent has turned off comments.
    Sorry, we can't delete your comment right now. Please try again later.
    You've exceeded the maximum number of comments that can be left in one day. Please try again in 24 hours.
    Your account has had the ability to leave comments disabled because our systems indicate that you may be spamming other users. If you believe that your account has been disabled in error please contact Windows Live support.
    Complete the security check below to finish leaving your comment.
    The characters you type in the security check must match the characters in the picture or audio.

    To add a comment, sign in with your Windows Live ID (if you use Hotmail, Messenger, or Xbox LIVE, you have a Windows Live ID). Sign in


    Don't have a Windows Live ID? Sign up

    Trackbacks

    The trackback URL for this entry is:
    http://seanxiaoxiao.spaces.live.com/blog/cns!7677365E5B9342DE!674.trak
    Weblogs that reference this entry
    • None