- 浏览: 495685 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (1028)
- [发布至博客园首页] (826)
- [随笔分类]个人生活随笔 (14)
- [网站分类]首页候选区 (26)
- [网站分类]SharePoint (15)
- [网站分类]其他技术区 (6)
- [随笔分类]批处理技巧 (6)
- [随笔分类].net 2.0 (3)
- [随笔分类]SharePoint2007(MOSS2007) (0)
- [网站分类].NET新手区 (6)
- [网站分类]ASP.NET (6)
- [网站分类]架构设计 (18)
- [网站分类]程序人生 (2)
- [网站分类]SQL Server (2)
- WCF (3)
- 编程技巧 (2)
- 模式架构 (2)
- 分析设计 (4)
- 生活随笔 (0)
- 软件工程 (1)
- Android实例 (2)
最新评论
-
zilong0536:
楼主您好:
请问发表博文支持图片的功能怎么实现啊,一直没有思路 ...
新浪微博开放平台开发-android客户端(3) -
nicegege:
小弟 学习了
帮助中国移动设计10086的排队小模块 -
zl7824516:
用什么技术没说啊
通告(公告),消息(站内短信),提醒的设计:通告 -
virusswb:
源码下载: SinaWeibo2 源码下载之后,将后缀改为ra ...
新浪微博开放平台开发-android客户端(3) -
Jimmyxu0311:
找不到源码下载
新浪微博开放平台开发-android客户端(3)
Head.First.Object-Oriented.Design.and.Analysis《深入浅出面向对象的分析与设计》读书笔记(五)
- 博客分类:
- [发布至博客园首页]
好的设计产生灵活的软件-上(good design = flexible software part 1)
------------没有什么是一成不变的nothing ever stays the same
引言 |
正文 |
先来看一个已有系统的类关系图。就是一个guitar销售商店,可以查询guitar,添加guitar。
客户说最近他想卖mandolins曼陀林(一种琵琶类乐器),想要我们在系统中实现这个功能,并且可以针对这种乐器进行搜索。
我们需要在原有系统中支持曼陀林这种新的乐器。既然是乐器,肯定和guitar有共同的地方,我们可以抽象出来。加入一个乐器类,表示曼陀林和guitar的抽象。
其实在上图中,我们会发现,乐器的细节类和guitar的细节类,以及mandolin的细节类都很相似,还应该有个抽象的乐器细节类。把共同的细节信息都移到抽象类中。
就会变成下面的结果
在UML图中
如上图所示,第一条是关系,也就是通常我们说的类之间的关系,1:1,1:n,n:1,之类的。第二条就是继承。第三条是集成,还不太理解,在后面理解了我们再来讨论他。
由上面最后的两张类图,我们可以写出下面的代码。
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BeautyCode.Common.ConApp.Head.First.OO.Design
{
public abstract class InstrumentSpec
{
private Builder _builder;
private InstrumentType _type;
private Wood _backwood;
private Wood _topwood;
public InstrumentSpec(Builder builder, InstrumentType type, Wood backwood, Wood topwood)
{
_builder = builder;
_topwood = topwood;
_type = type;
_backwood = backwood;
}
public virtual bool Matches(InstrumentSpec instance)
{
if (instance._builder != _builder)
return false;
if (instance._backwood != _backwood)
return false;
if (instance._topwood != _topwood)
return false;
if (instance._type != _type)
return false;
return true;
}
}
public abstract class Instrument
{
private string _serialNumber;
public string SerialNumber
{
get { return _serialNumber; }
}
private double _price;
public double Price
{
get { return _price; }
}
private InstrumentSpec _spec;
public InstrumentSpec Spec
{
get { return _spec; }
}
public Instrument(string serialNumber, double price, InstrumentSpec spec)
{
_serialNumber = serialNumber;
_price = price;
_spec = spec;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BeautyCode.Common.ConApp.Head.First.OO.Design
{
public class GuitarSpec : InstrumentSpec
{
private int _numString;
public int NumString
{
get { return _numString; }
}
public GuitarSpec(Builder builder, InstrumentType type, Wood backwood, Wood topwood, int numString)
: base(builder,
type, backwood, topwood)
{
this._numString = numString;
}
public override bool Matches(InstrumentSpec instance)
{
if (!base.Matches(instance))
return false;
if (!(instance is GuitarSpec))
return false;
GuitarSpec spec = instance as GuitarSpec;
if (spec._numString != _numString)
return false;
return true;
}
}
public class Guitar : Instrument
{
public Guitar(string serialNumber, double price, GuitarSpec spec)
: base(serialNumber, price, spec)
{
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BeautyCode.Common.ConApp.Head.First.OO.Design
{
public class MandolinSpec : InstrumentSpec
{
private Style _style;
public Style Style
{
get { return _style; }
}
public MandolinSpec(Builder builder, InstrumentType type, Wood backwood, Wood topwood, Style style)
: base(builder,
type, backwood, topwood)
{
this._style = style;
}
public override bool Matches(InstrumentSpec instance)
{
if (!base.Matches(instance))
return false;
if (!(instance is GuitarSpec))
return false;
MandolinSpec spec = instance as MandolinSpec ;
if (spec._style != _style )
return false;
return true;
}
}
public class Mandolin : Instrument
{
public Mandolin(string serialNumber, double price, MandolinSpec spec)
: base(serialNumber, price, spec)
{
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BeautyCode.Common.ConApp.Head.First.OO.Design
{
public class Inventory
{
private List<Instrument> _inventory;
public Inventory()
{
_inventory = new List<Instrument>();
}
public void AddInstrument(string serialNumber,double price,InstrumentSpec spec)
{
Instrument instance = null;
if (spec is GuitarSpec)
{
instance = new Guitar(serialNumber, price,(GuitarSpec ) spec);
}
else if (spec is MandolinSpec)
{
instance = new Mandolin(serialNumber, price, (MandolinSpec)spec);
}
_inventory.Add(instance);
}
public Instrument Get(string serialNumber)
{
return _inventory.Find(i => i.SerialNumber == serialNumber);
}
public List<Instrument> Search(MandolinSpec searchSpec)
{
List<Instrument> instances = _inventory .FindAll(i => i.Spec.Equals(searchSpec));
return instances;
}
}
}
是否这个就满足了要求了呢?现在看来是满足了用户的新要求。
检查软件是否设计良好的一个方法就是加入变化,然后看看它是怎么适应变化的。
现在如果要添加一个新的乐器类型,并且有对应的search方法。需要继承instrument基类,然后要修改inventory类,增加针对新乐器的search方法。当然了,增加新乐器,增加一个他的类和明细类没有问题,肯定是需要的。但是增加新乐器就修改一次inventory类,好像不太应该吧。
让我们来引入一个新的概念:接口。
接口是什么呢?接口是用来定义行为的,定义通用的行为。
假设我们的系统有一个接口,很多类都通过实现这个接口来拥有常用的方法。编程的时候可以使用具体类,也可以使用接口。使用接口可以增加灵活性。你的代码工作在接口之上,就不用每次增加新类型就修改代码了。只要新类型实现接口就可以了。当然了,你也不要叫真,没有关系的,也不用非要实现接口。只是需要具有通用行为的类实现接口就行了。记住,接口是用来定义共同行为的。
在你进行代码工作的任何时候,对类进行操作,你都有两个选择。你可以直接针对子类写代码,也就是FootballPlayer,也可以针对接口IAthlete写代码。当你面临这种抉择的时候,你应该记住:要针对接口编程,不要针对实现编程。
为什么呢?就是为了给你的应用增加灵活性。在针对接口IAthlete编程之后,你的代码可以适用更多类型的athlete。而不用增加一种类型的athlete就为它们写一套重复的代码,给维护带来很大的麻烦。
下面我们来解释一些概念
1、封装
在前面我们已经了解到,封装就是为了减少代码的复制。使用封装避免大量的copy-and-paste。封装还可以使你的类避免不必要的改变。
在你的应用中,如果有的行为可能会发生变化,你就需要将这部分变化从很少变化的代码中移出来。换句话说,也就是封装变化,对可能经常变化的地方进行封装。
2、变化
你已经知道,在软件中唯一不变的就是变化。设计良好的软件很容易应对变化。
最简单的办法就是保持软件的弹性,使得每个类只有一个改变它的原因。
结论 |
OO原则:
- 封装变化
- 针对接口编程,不针对实现编程
- 每一个类应该只有一个改变他的原因
发表评论
-
NET 应用架构指导 V2 学习笔记(十六) 服务层设计指导
2010-06-04 00:13 547如果你的应用是通 ... -
NET 应用架构指导 V2 学习笔记(十七) 组件设计指导
2010-06-05 00:48 669组件提供了一种将 ... -
NET 应用架构指导 V2 学习笔记(十八) 表现层组件设计指导
2010-06-05 21:09 528本章讲述的是你在设计用户界面组件和表现层逻辑组件的时候应该 ... -
NET 应用架构指导 V2 学习笔记(十九) 表现层组件设计指导
2010-06-06 06:15 5915 决定数据绑定的 ... -
NET 应用架构指导 V2 学习笔记(二十) 业务组件设计指导
2010-06-07 06:58 614前言 业务组件 ... -
微软企业库5.0学习笔记(四十二)异常处理模块
2010-06-14 00:04 836企业库的异常处理 ... -
关于程序员在30岁、35岁之后怎么办的新思考
2010-06-14 10:40 624首先给大家问个好 ... -
NET 应用架构指导 V2 学习笔记(二十四) 跨层关注问题
2010-06-17 20:00 594概况 大部分的 ... -
微软企业库5.0学习笔记(四十三)数据验证模块
2010-06-19 08:07 996概况 任何接受用户或者是其他系统输入的应用,一定要确保 ... -
关于项目进度慢的思考----如何提高整体开发效率
2010-06-21 23:42 803我们都是软件行业 ... -
微软企业库5.0学习笔记(四十四)实战数据验证模块
2010-06-23 19:22 8401 在业务对象上添加验证 添加对程序集【Microso ... -
微软企业库5.0学习笔记(四十五)实战数据验证模块----高级篇
2010-06-24 19:41 9691、添加自定义的提示信息 验证失败的提示信息可以自定义 ... -
面向对象类设计的五大原则(一)单一职责原则Single Responsibility Principle
2010-06-29 15:45 777引言 面向对象类设计,或者说是面向对象设计,有五大原则 ... -
《深入浅出设计模式-中文版》读书笔记 开篇乱弹(一)
2010-07-01 06:42 650oreilly的《Head.First ... -
《深入浅出设计模式-中文版》读书笔记-继承与组合(三)
2010-07-03 16:53 605经过上一次的改造 ... -
《深入浅出设计模式-中文版》读书笔记-观察者模式(四)
2010-07-06 06:34 633今天要接触的是观 ... -
利用attribute实现简单的ORM
2010-07-09 15:27 682我不知道NH的ORM具 ... -
系统内部模块(子系统)之间的耦合以及模块(子系统)划分
2010-07-14 13:02 807题外话 最近已经在努力学习了,学习基本功,学习设计模式 ... -
《深入浅出设计模式-中文版》读书笔记-工厂模式(五)
2010-07-16 12:46 699今天给大家带来的是:工厂模式。 我们在代码中创建一个对 ... -
Head.First.Object-Oriented.Design.and.Analysis《深入浅出面向对象的分析与设计》读书笔记(一)
2010-07-18 21:47 671题外话 又是一本Head.First系列的书,这个系列 ...
相关推荐
深入浅出面向对象的分析与设计Head.First.Object-Oriented.Design.and.Analysis这本书以较轻快的语气为我们讲述了面向对象的分析与设计,适合精读,多读,仔细揣摩其中的思想
深入浅出面向对象的分析与设计,Head.First.Object-Oriented.Design
深入浅出面向对象的分析与设计Head.First.Object-Oriented.Design.and.Analysis 从自己做起 OOAD真正应用在你的项目中
“《深入浅出面向对象分析与设计》对OOA&D这个主题的探讨令人耳目一新。 本书与众不同之处在于它将焦点摆在学习上,本书的诸位作者让从业人员对OOA&D的内涵不再感到遥不可及,而且它在实际工作中确实有用。” ...
Head.First.Object-Oriented.Design.and.Analysis.part5
“《深入浅出面向对象分析与设计》对OOA&D这个主题的探讨令人耳目一新。 本书与众不同之处在于它将焦点摆在学习上,本书的诸位作者让从业人员对OOA&D的内涵不再感到遥不可及,而且它在实际工作中确实有用。” ...
Head.First.Object-Oriented.Design.and.Analysis.part4
Head.First.Object-Oriented.Design.and.Analysis.part1
Head.First.Object-Oriented.Design.and.Analysis.part2
Head.First.Object-Oriented.Design.and.Analysis.part3
Head.First-深入浅出面向对象分析与设计-中文.part08
“《深入浅出面向对象分析与设计》对OOA&D这个主题的探讨令人耳目一新。 本书与众不同之处在于它将焦点摆在学习上,本书的诸位作者让从业人员对OOA&D的内涵不再感到遥不可及,而且它在实际工作中确实有用。” ...
Head.First 面向对象编程原汁原味英文版
Head First Object-Oriented Design and Analysis 英文版,共3个文件
《Head First 对象导向分析与设计》是一本旨在帮助读者深入理解对象导向分析与设计(Object-Oriented Analysis and Design,简称 OOA&D)核心概念的专业书籍。该书通过丰富的图形和实例来阐述复杂的理论知识,使学习...