[Java 程序员应当知道的 10 个面向对象设计原则] - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
showMeYourCode
V2EX    Java

[Java 程序员应当知道的 10 个面向对象设计原则]

  •  
  •   showMeYourCode 2016-01-05 14:22:37 +08:00 2608 次点击
    这是一个创建于 3635 天前的主题,其中的信息可能已经有所发展或是发生改变。

    面向对象设计原则是 OOPS ( Object-Oriented Programming System ,面向对象的程序设计系统)编程的核心, 但我见过的大多数 Java 程序员热心于像 Singleton (单例) 、 Decorator (装饰器)、 Observer (观察者) 等设计模式,而没有把足够多的注意力放在学习面对象的分析和设计上面。学习面向对象编程像“抽象”、“封装”、“多态”、“继承” 等基础知识是重要的,但同时为了创建简洁、模块化的设计,了解这些设计原则也同等重要。我经常看到不同经验水平的 java 程序员,他们有的不知道这些 OOPS 和 SOLID ( PS :请看最后的解释)设计原则,有的只是不知道一个特定的设计原则会带来怎样的益处,甚至不知道在编码中如何使用这些设计原则。

    1.(设计原则)
    底线是永远追求高内聚、低耦合的编码或设计。 Apache 和 Sun 的开源代码是学习 Java 和 OOPS 设计原则的良好范例。它们向我们展示了,设计原则在 Java 编程中是如何使用的。 Java JDK 使用了一些设计原则: BorderFactory 类中的工厂模式、 Runtime 类中的单例模式、 java.io 类中的装饰器模式。顺便说一句,如果您真的对 Java 编码原则感兴趣,请阅读 Joshua Bloch 的 Effective Java ,他编写过 Java API 。我个人最喜欢的关于面向对象设计模式的是 Kathy Sierra 的 Head First Design Pattern (深入浅出设计模式),以及其它的关于深入浅出面向对象分析和设计。这些书对编写更好的代码有很大帮助,充分利用各种面向对象和 SOLID 的设计模式。

    虽然学习设计模式(原则)最好的方法是现实中的例子和理解违反设计原则带来的不便,本文的宗旨是向那些没有接触过或正处于学习阶段的 Java 程序员介绍面向对象设计原则。我个人认为 OOPS 和 SOLID 设计原则需要有文章清楚的介绍它们,在此我一定尽力做到这点,但现在请您准备浏览以下设计模式(原则)。
    DRY Don ’ t repeat yourself
    我们第一个面向对象设计原则是: DRY ,从名称可以看出 DRY ( don ’ t repeat yourself )意思是不写重复代码,而是抽象成可复用的代码块。如果您有两处以上相同的代码块,请考虑把它们抽象成一个单独的方法;或者您多次使用了硬编码的值,请把它们设置成公共常量。这种面向对象设计原则的优点是易于维护。重要的是不要滥用此原则,重复不是针对代码而是针对功能来说。它的意思是,如果您使用通用代码来验证 OrderID 和 SSN ,这并不意味着它们是相同的或者他们今后将保持不变。通过把通用代码用于实现两种不同的功能,或者您把这两种不同的功能密切地联系在一起;当您的 OrderID 格式改变时,您的 SSN 验证代码将会中断。所以要当心这种耦合,而且不要把彼此之间没有任何关系却类似的代码组合在一起。

    2.封装经常修改的代码
    Encapsulate What Changes
    在软件领域永远不变的是“变化”,所以把您认为或怀疑将来要被修改的代码封装起来。这种面向对象设计模式的优点是:易于测试和维护恰当封装的代码。如果您在用 Java 编程,那么请遵守以下原则:变量和方法的访问权限默认设置为私有,并且逐步放开它们的访问权限,例如从“ private ”到“ protected ”、“ not public ”。 Java 中的一些设计模式使用了封装,工厂设计模式就是一个例子,它封装了创建对象的代码而且提供了以下灵活性:后续生成新对象不影响现有的代码。

    3.打开 /关闭设计原则
    OpenClosed Design Principle
    类、方法 /函数应当是对扩展(新功能)开放,对修改闭合。这是另外一个优雅的 SOLID 设计原则,以防止有人修改通过测试的代码。理想情况下假如您添加了新功能,那么您的代码要经过测试,这就是打开 /关闭设计原则的目标。顺便说一句, SOLID 中的字母“ O ”指的是打开 /关闭设计原则。

    4.单一职责原则
    Single Responsibility Principle(SRP)
    单一职责原则是另外一个 SOLID 设计原则, SOLID 中的字母“ S ”指的就是它。按照 SRP ,一个类修改的原因应当有且只有一个,或者一个类应当总是实现单一功能。如果您在 Java 中的一个类实现了多个功能,那么这些功能之间便产生了耦合关系;如果您修改其中的一个功能,您有可能就打破了这种耦合关系,那么就要进行另一轮测试以避免产生新的问题。

    5.依赖注入 /反转原则
    Dependency Injection or Inversion principle
    不要问框架的依赖注入功能将会给你带来什么益处,依赖注入功能在 spring 框架里已经很好的得到了实现,这一设计原则的优雅之处在于: DI 框架注入的任何一个类都易于用模拟对象进行测试,并且更易于维护,因为创建对象的代码在框架里是集中的而且和客户端代码是隔离的。有多种方法可以实现依赖注入,例如使用字节码工具,其中一些 AOP(面向切面编程)框架如切入点表达式或者 spring 里使用的代理。想对这种 SOLID 设计原则了解更多,请看 IOC 和 DI 设计模式中的例子。 SOLID 中的字母“ D ”指的就是这种设计原则。

    6.优先使用组合而非继承
    Favor Composition over Inheritance
    如果可以的话,要优先使用组合而非继承。你们中的一些人可能为此争论,但我发现组合比继承更有灵活性。组合允许在运行时通过设置属性修改一个类的行为,通过使用多态即以接口的形式实现类之间的组合关系,并且为修改组合关系提供了灵活性。甚至 Effective Java 也建议优先使用组合而非继承。

    7.里氏替换原则
    Liskov Substitution Principle LSP
    根据里氏替换原则,父类出现的地方可以用子类来替换,例如父类的方法或函数被子类对象替换应该没有任何问题。 LSP 和单一职责原则、接口隔离原则密切相关。如果一个父类的功能比其子类还要多,那么它可能不支持这一功能,而且也违反了 LSP 设计原则。为了遵循 LSP SOLID 设计原则,派生类或子类(相对父类比较)必须增强功能,而非减少。 SOLID 中的字母“ L ”指的就是 LSP 设计原则。

    8.接口隔离原则
    接口隔离原则指,如果不需要一个接口的功能,那么就不要实现此接口。这大多在以下情况发生:一个接口包含多种功能,而实现类只需要其中一种功能。接口设计是一种棘手的工作,因为一旦发布了接口,您就不能修改它否则会影响实现该接口的类。在 Java 中这种设计原则的另一个好处是:接口有一个特点,任何类使用它之前都要实现该接口所有的方法,所以使用功能单一的接口意味着实现更少的方法。

    9 编程以接口(而非实现对象)为中心
    编程总是以接口(而非实现对象)为中心,这会使代码的结构灵活,而且任何一个新的接口实现对象都能兼容现有代码结构。所以在 Java 中,变量、方法返回值、方法参数的数据类型请使用接口。这是许多 Java 程序员的建议, Effective Java 以及 head first design pattern 等书也这样建议。( PS :这两本是非常不错的 Java 好书,推荐入门后学习,有一定难度)

    10.代理原则
    不要期望一个类完成所有的功能,可以适当地把一些功能交给代理类实现。代理原则的典范是: Java 中的 equals() 和 hashCode() 方法。为了比较两个对象的内容是否相同,我们让用于比较的类本身完成对比工作而非它们的调用方。这种设计原则的好处是:没有重复编码而且很容易修改类的行为。

    总结
    以上所有面向对象的设计原则可以帮助您写出灵活、优雅的代码:具有高内聚低耦合的代码结构。理论只是第一步,更重要的是我们要习得一种能力去发现什么时候使用这些设计原则。去发现我们是否违反了什么设计原则和影响了代码的灵活性,但是世界上没有什么是完美的,我们解决问题时不能总去使用设计模式和设计原则,它们大多用于有较长维护周期的大型企业项目。
    首先解释一下 SOLID : S.O.L.I.D 是面向对象设计和编程(OOD&OOP)中几个重要编码原则的首字母缩写。
    SRP ( The Single Responsibility Principle )单一责任原则
    OCP ( The Open Closed Principle )开放封闭原则
    LSP ( The Liskov Substitution Principle )里氏替换原则
    DIP ( The Dependency Inversion Principle )依赖倒置原则
    ISP ( The Interface Segregation Principle )接口分离原则
    这些 OO 原则可以说是面向对象编程的精髓所在,好比易筋经之心法,想要运用自如,需要长时间的编码积累体会,着急不得。但又要避免滥用,由其是在 JavaEE 开发和 Android 开发中,要以实际项目需求出发,不过,一切原则以扩展性和性能来权衡考虑,总是不会错的。

    [-文章节选自同行说应用,看更过技术干货请移步同行说]

    目前尚无回复
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5605 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 37ms UTC 06:30 PVG 14:30 LAX 22:30 JFK 01:30
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86