设计模式学习笔记(一)——面向对象设计模式与原则

转载 2007年09月18日 12:01:00

 今天听了《C#面向对象设计模式纵横谈(1):面向对象设计模式与原则》课程。总结了一些笔记。
 首先介绍了什么是设计模式:设计模式描述了软件设计过程中某一类常见问题的一般性的解决方案。
 下面主要讨论面向对象设计模式。
 面向对象设计模式描述了类与相互通信的对象之间的组织关系。目的是应对变化、提高复用、减少改变。
 那到底什么是对象:
  1、从概念层面讲,对象是某种拥有职责的抽象;
  2、从规格层面讲,对象是一系列可以被其他对象使用的公共接口;
  3、从语言实现层面来看,对象封装了代码和数据(也就是行为和状态)。
 对于这三点,我理解最深的应该是第三点。这可能和我把大多精力放在了代码实现上有关,然而忽略了编程的的思想。如果我们抛开代码的实现来看对象的概念,那么它应该就像一个具体的物体,比如说:榔头,从概念层面讲,榔头有它的职责,也就是它是做什么用的(用来砸钉子,当然还会有其他用途,如防身),从规格层面讲,比如人使用榔头砸钉子。
 面向对象的设计模式有三大原则:
  1、这对接口编程,而不是针对实现编程。在知道设计模式之前,我对接口的出现很不理解。不明白为什么这个什么都不能实现的东西会存在,当然,也对多态表示茫然。实际上我是还没有理解面向对象编程的思想。在对设计模式略有了解后发现接口的确是一个好东西,用它实现多态的确减少了代码的修改。
 比如说在《Head First Design Patterns》中有一个例子,说一个有关鸭子的游戏。游戏当中有很多种的鸭子,如:野鸭,木头鸭,鸭子模型。我们首先会想到做一个抽象类:abstract class Duck,Duck当中有很多的抽象属性和方法,如quack。我们用子类继承的时候都会实例化这个方法。
 public abstract class Duck
 {
  public abstract void quack()
 }
 
 public class MallardDuck:Duck
 {
  public override void quack()
  {
   Console.Write("I can quack");
  }
 }
当程序成型后,我们有了很多种鸭子,突然,我们发现有的鸭子会飞,我们会在Duck中在加上一个抽象方法abstract void fly();于是我们不得不在所有的子类当中添加fly的实现,有人会说,如果我们在Duck中直接添加fly的实现,不久不用在子类中添加实现了吗?那老板就该问你:你见过木头鸭子满天飞(哦,天啊!木头鸭子也飞起来了,这是什么世界!)。对不起老板,现在咱们都见到了。
 这时我们换一种想法,如果我们把这些方法都提取出来,把它变成Duck的成员,好像问题就会简单些。
 哈哈,好像扯的有点远了,现在回来接着记我的笔记。
  2、优先使用对象组合,而不是类的继承。
 这就使说多使用“has a”,少使用“is a”,哈哈,我又想说回刚才的例子。换个角度考虑Duck及其功能,我们设计一个fly的接口和一些具体的飞行方法。
 public interface FlyBehavior
 {
  void fly();
 }

 public class FlyWithWing:FlyBehavior
 {
  public void fly()
  {
   Console.Write("I can fly/n");
  }
 }

 public class FlyNoWay:FlyBehavior
 {
  public void fly()
  {
   Console.Write("I can't fly/n");
  }
 } 
 好了,对于Duck来说,现在它应该有一个(has a)fly的方法
 public abstract class Duck
 {
  public Duck()
  {}
  public FlyBehavior flybehavior; 
 }
 现在我们再来实现两种鸭子
 public class ModelDuck:Duck
 {
  public ModelDuck()
  {
   flybehavior = new FlyNoWay();
  }
 }
 
 public class MallardDuck:Duck
 {
  public MallardDuck()
  {
   flybehavior = new FlyWithWing();
  }
 }
 这样如果要是在加上某种行为的话,我们就不必在每一种鸭子上下功夫。把注意力放在我们关心的鸭子品种上(别太使劲关注,小心禽流感,“阿切!”)。
  3、封装变化点,实现松耦合,这点不用多说了。
 课程中提到,编码当中的设计模式使用不是我们在编程之初就定下来的,应该是重构得到设计模式(Refactoring to Patterns)。哦,原来是这样,也好理解。在编码中遇到问题,然后想想应对方式。哈哈,我原来认为开始编程时就指定我们用什么设计模式呢。
 下面说说设计原则:
  1、单一职责原则(SRP):一个类应仅有一个引起它变化的原因。
  2、开放封闭原则(OCP):类模块应可扩展,不可修改。这里要说明一下,扩展和修改是不同的。比如:我们要在加一种ModelDuck,那么我们写一个ModelDuck的类继承Duck,这叫扩展,不是修改。什么是修改,就好像我们开始说的那种作法,为了加一个fly的功能,我们要把所有的子类中加入不同的实现,这叫修改。
  3、Liskov替换原则:子类可替换基类。
  4、依赖倒置原则:高层模块不依赖于低层模块,二者都依赖于抽象。还是刚才的例子:Duck是一个高层模块,fly是低层模块。Duck不依赖于fly,高层模块的改变慢,而低层模块的改变慢。
     抽象不应依赖于实现细节,实现细节应依赖于抽象。fly是一个抽象,它不依赖如何飞行。
  5、接口隔离原则:不强迫客户程序依赖于它们不用的方法(有道理,木头鸭子不会飞为什么要让它实现飞的功能。)
  最后有人提问接口和抽象类的区别:
   接口可以多继承,抽象类只能但继承。接口定义组件间的合同。使用抽象类为一个is a的关系。

 

相关文章推荐

设计模式学习笔记系列(一)——面向对象设计原则

学习设计模式重要的不是你将来会不会用到这些设计模式,而是通过这些模式让你找到“封装变化”、“对象间松散耦合”、“针对接口编程”的感觉,从而设计出易维护、易扩展、易复用、灵活性好的的程序。面向对象设计的...

[设计模式学习笔记一][面向对象七大设计原则]

[设计模式学习笔记一][面向对象七大设计原则]

设计模式学习笔记--面向对象设计原则

设计模式学习笔记–面向对象设计原则面向对象设计原则 单一职责原则 开闭原则 里氏替换原则 依赖倒转原则 接口隔离原则 合成复用原则 迪米特法则

《Android源码设计模式解析与实战》读书笔记(一)——面向对象的六大原则

写代码很容易,但是写出简单易懂好修改的代码实在。如何优化代码,设计模式是关键,所以最近开始啃书,在这里记录一下读书笔记,大部分是摘录,也有自己的总结和心得,写给自己。 第一章、面向对象的六大原则 1....

[笔记]00面向对象设计模式与原则

这个是MSDN广播的课程,05年的课程,作者是李建忠先生,今日观看依然有豁然开朗之感。其中总总知识与思想渐渐能在皮毛上跟上作者的思路。顾记录下些许笔记,记录点滴。继寒假时使用思维导图方式记录笔记,今年...

Java设计模式——面向对象的几个基本原则

1. 面向抽象原则 1.1 抽象类 1.2 接口 1.3 面向抽象 2. 开-闭原则 3. 多用组合少用继承原则 3.1 继承与复用 3.2 组合与复用 4. 高内聚-低耦合原则
  • ayhlay
  • ayhlay
  • 2013-09-04 18:24
  • 4428

Java设计模式之——面向对象六大原则

设计模式六大原则(1):单一职责原则设计模式六大原则(2):开闭原则设计模式六大原则(3):里氏替换原则设计模式六大原则(4):依赖倒置原则设计模式六大原则(5):接口隔离原则设计模式六大原则(6):...
  • AkaiC
  • AkaiC
  • 2016-10-27 20:51
  • 1237

android 源码设计模式解析与实战 读书笔记 1 面向对象的六大原则

六大原则包括单一职责原则,开闭原则,里氏替换原则,依赖倒置原则,接口隔离原则,迪米特原则。 单一职责原则:一个类中应该是一组相关性很高的函数,数据的封装。举例:将ImageLoader中抽取Image...

Android源码设计模式解析与实战——面向对象六大原则(一)

最近在看《Android源码设计模式解析与实战》,希望通过记笔记,监督自己,也方便以后查询。

Java基础06天 学习笔记_面向对象(Static静态,JavaAPI,单例设计模式)

01 Static 关键字 多个对象中存在共同数据: 如 country (CN) 没有必要没一个对象都有一个CN, 浪费空间   static String country = "...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)