学习面向对象的设计原则

现在是OO语言流行的时代,但是我们真的能深入运用OO的特性来进行软件开发,或是在开发一套纯的软件系统吗?我想绝大部分人不敢站出来肯定自己所参与开发的是一套纯正的具有OO血统的系统!(不过,技术是为需求而用,有些地方可能确实一时之间难以利用OO思维去思考)。

但无论如何,我们如今的软件开发都强调OO,那么,作为OO基础的知识,我们真的能掌握了吗?其实掌握了的人,在现实的软件开发中,还是不能第一时间用OO考虑如何解决问题?可能都是我们作为程序员的思维一定局限吧,既是用一般的面向过程去考虑如何解决一个问题(或需求)。还记得从《设计模式解析》这本书上,作者提到,我们应该学会用模式去思考!这个不得不引起我们的沉思!我想我们作为一名程序员,不能过于浮躁,但现今的社会又有哪个能做到呢?算了吧,还是看看我们OOD中的最基本的原则吧!好好学习一番,算是给自己复习,净化自己的浮躁的心!

【引】在面向对象设计中,如何通过很小的设计改变就可以应对设计需求的变化,这是令设计者极为关注的问题。为此不少OO先驱提出了很多有关面向对象的设计原则用于指导OO的设计和开发。当然,在此,我们更不可忘掉OO中的三大特性吧,抽象、封装、多态。《Leaning Design Patterns by Looking at code》的作者就说过,85%的软件开发都是面向接口(即面向抽象)、多态编程!

  1. 我们先来看看在面向对象中有哪些设计原则,follow:

    关于类设计的


    • OCP开放封闭原则 (Open Close Principle),软件实体(类、模块、函数)在扩展性方面应该是开放的而在更改性方面应该是封闭的。在进行面向对象设计时要尽量考虑接口封装机制、抽象机制和多态技术。该原则同样适合于非面向对象设计的方法,是软件工程 设计方法的重要原则之一。
    • 通过一些例子来描述吧
    • 这是一个违背了OCP原则的例子,每当我们要添加一个图形的时候,都要修改代码,影响到已存在的功能。
      Open Close Principle(OCP) - bad
  • // Open-Close Principle - Bad example
  • class GraphicEditor {
    •     public void drawShape(Shape s) {
  •          if (s.m_type==1)
  •              drawRectangle(s);
  •         else if (s.m_type==2)
  •             drawCircle(s);
  •       }
  •       public void drawCircle(Circle r) {....}
  •       public void drawRectangle(Rectangle r) {....}
  • }
  • class Shape {
  •      int m_type;
  • }
  • class Rectangle extends Shape {
  •          Rectangle() {
  •                  super.m_type=1;
  •          }
  • }
  • class Circle extends Shape {
  •          Circle() {
  •          super.m_type=2;
  •           }
  • }

上面的几个缺点:
每增加一个图形,对于GraphicEditor都要重做一次单元测试
当一个新图形被添加时,都要求开发人员理解GraphicEditor里面的程序逻辑
添加一个新图形在我们不期望的方式来影响程序现有的缺点,即使新添的图形能运行良好。

看用OCP原则来重新设计上面的例子

Open Close Principle(OCP) - good

// Open-Close Principle - Good example
class GraphicEditor {
public void drawShape(Shape s) {
s.draw();
}
}

class Shape {
abstract void draw();
}

class Rectangle extends Shape {
public void draw() {
// draw the rectangle
}
}

  1. SRP单一职责原则 (Single Responsiblity Principle),就一个类而言,应该仅有一个引起它变化的理由。
  2. LSPLiskov替换原则 ,子类应当可以替换父类并出现在父类能够出现的任何地方。
  3. DIP依赖倒置原则 (Dependency Inversion Principle),依赖关系应该尽量依赖接口与抽象类(即是依赖抽象),而不是依赖于具体类。
  4. ISP接口隔离原则 (Interface Segregation Principle),采用多个与特定客户类有关的接口比采用一个通用的涵盖多个业务方法的接口要好。

    对于另外六项原则,则都是关于包的设计原则。在这里,包是指一个二进制的可发布文件,如Jar文件、DLL文件等。不等同于Java语言中的package或C++的命名空间之类
关于包内聚性的:
  • REP,重用发布等价原则 ,重用的粒度就是发布的粒度。
  • CPP,共同封闭原则 ,包中的所有类对于同一类性质的变化应该是共同封闭的。
  • CRP,共同重用原则 ,一个包中的所有类应该是共同重用的。
关于包之间的耦合性原则的:
  • ADP,无环依赖原则,在包的依赖关系图中不允许存在环。
  • SDP,稳定依赖原则,朝着稳定的方向进行依赖。
  • SAP,稳定抽象原则,包的抽象程度应该和其稳定程度一致。

在以上的OOD原则中,开发中常见的应该是前面介绍到关于类设计的几个原则。在进行面向对象的软件开发过程中,当然,我们不可能时刻把这些原则挂在嘴边,重要的是时刻惦记着尽可能使用在开发过程中。但是,我们应该要时刻审视我们自己的代码是否符合基本的原则,在软件开发中,最重要的还是如何去建立“松耦合”。

代码和图片来源自【http://www.oodesign.com/ 】,还有其他的内容来自互联网,总之,感谢分享知识的人们!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值