LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 3488|回复: 16

设计模式再读 原创

[复制链接]
发表于 2004-6-26 20:27:22 | 显示全部楼层 |阅读模式
原创 无双 发表于loveunix.net
转载请与原作者联系 lizlok@gmail.com

出差回来 看到那么多电脑书好久没看了 于是重拿起来一本一本的学习

重读了一下设计模式 这次准备使用简单的语言来写

不求别人理解 只求记录自己的心得

所以这并不是一个教程 如果想学习的话 最好还是一边看原书一边讨论吧

另外书中内容只是本人见解 并不保证100%正确
 楼主| 发表于 2004-6-26 20:30:06 | 显示全部楼层
1
什么是设计模式

设计就是解决方案 对某个问题的解决

如果某个解决方案对某类问题都很有用 这时就把它总结出来

这就产生了设计模式
 楼主| 发表于 2004-6-26 20:33:33 | 显示全部楼层
设计模式的要素

1 名称 用于助记 .道可道 非常道 名可名 非常名 起这个名只是表示形象表示这个模式

2 问题 这个模式可以解决什么问题

3 解决方案 这个模式怎样解决这个问题的 步骤与方法

4 效果 使用这个模式与不使用这个模式有什么区别 它有什么优点和缺点

开发程序应该知道 一个问题可以有多种解法 好的解法都可以找到很多种 每种都有乱缺点
所以写代码时不要死记方法 应该活用 软件开发并不是小学老师教的不是好就是坏
 楼主| 发表于 2004-6-26 20:56:21 | 显示全部楼层
MVC模型

每本设计模式或是面向对象的书都会见到MVC
它们或是表现自己深沉或是借助它来表现最原始的设计方法

所以 懂MVC还是有必要的

MVC(Model/View/Controler)是模型/视图/控制器 最先出现于smalltalk语言
在面向对象中 模型就是对象 视图是对象的表示 控制就是对象的控制接口

class A{
private:
int i;
public:
void add();
void showinhex();
void showinbin();
};

A a;
a就是模型
add就是控制器 通过它来改变对象的状态
用户对i的解释就是视图的表现 也就是 数据在那里 用户可以根据自己的需要使用不同的方法来解释i 不同的表现并不会修改对象的状态 这些表现只是根据自己的需要来表现对象的状态
另外 视图并不一定是显示 而是自己对这个状态的解释

将控制与表现分开是一种最基本的设计模式 可以使双方独立的变化 一方变化不会影响另一方

如果使用vc开发的话 会懂得文档/视图模式 这就是mvc的一个应用表现
 楼主| 发表于 2004-6-26 20:58:23 | 显示全部楼层
设计模式的中主要方法与目标

软件是在不断进化的 需求在不断改变 所以软件应该适应变化
设计模式是为了让软件更加可适应变化 有更多的可复用性 也就是有变化时你不用从头重写一次这个软件

说到这里不得不提一下XP方法
XP方法(极限编程)的口号就是 简单就是最好 你今天写的到明天将不再使用
提倡简单(不用为现在不使用的功能而添加代码),
沟通(配对编程与不断的进行开会沟通),
测试(保证已开发部分的稳定性),
重构(保证软件结构适合变化)
另外提倡小设计,这些小设计只是为了完成当前模块,为了方便当前沟通而使用 并不会进行归档
与传统设计需要有很多的设计文档(概要与详细设计 )并且需要进行同步不同 XP认为没有同步的文档比没有文档更差 不提倡文档也是XP的一个很特别的特点

极限编程当发现软件结构不适合变化时 就建议进行重构 保证软件结构的完善
一般人可能会因为重构而认为它不提倡设计模式或软件设计
认为如果软件写不好就进行简单的重写
但是 极限编程也是讲究设计的 当然这个设计只是针对当前模块

我觉得XP方法就像是积木的办法 先把一块一块的积木搭好 每到一个阶段就进行检查 保证质量 最后组成一个大系统
 楼主| 发表于 2004-6-26 21:32:33 | 显示全部楼层
要使一个软件更适应变化 就应该封装变化 让变化的影响最小
另外就是封装复杂性 提供简单的接口

通常有下面几种形式

1 松耦合
软件分成模块 大的软件都是由一个一个小模块组成的 小模块还可能再由更小的模块组成
一个模块就是相互间联系紧密的变量与函数 或对象 不同模块间关系比较松散
模块间关系越松散 这样修改一个模块时 对其它模块的影响就越小 这样可以把变化限制在一个模块内

2 针对接口编程 而不是针对实现编程
具体来说就是 你只要定义这个接口有什么功能 不用定义它是什么实现的
当其它模块需要这个功能时 只要调用这个接口就可以 它不必了解你的实现机制
当你换一个实现时 就不会同时修改其它模块

3 继承 组合 委托与多态与参数化
继承是有父子关系的对象的具体化
组合就是把有相互关系的对象放在一起 由它们提供某一个或一组功能 这功能需要它们共同配合才能实现
委托是一个对象把一个请求转交给另一个对象执行 相当歌手与经济人的关系 经济人是委托者 歌手是执行者
多态就是实现的可替换性 你可以在运行时使用另一种实现来代替当前实现而不必修改代码
参数化就是根据不同类型的参数提供不同的功能 如c++中的模板机制 如vector类

这些是设计中常用的方法 同时也是c++语言提供的功能 应该理解
 楼主| 发表于 2004-6-26 21:33:56 | 显示全部楼层
c++语言的特点

想使用设计模式 就应该对某种语言进行具体的了解 这样才能更好的使用这种语言来进行设计

c++语言引入的对象的概念 为的是更符合人们对自然的认识 所以学习c++或使用c++时 不应该把它看成一种机器语言 而应该看成是自己思考的办法
下面列出c++语言提供的功能


1 类
类就是某一类东西 类定义了这类东西共同的内容与操作 当然这些内容与操作是你所感兴趣的 衣服 是一类东西 它有很多特点 如果你只关心它的样式 那可以只定义对样式的操作
class clothes{
private:
int type;
public:
void settype();
int gettype();
};


2 封装
某些内容 你只想自己使用 而不想让其它对象能够访问 这时就可以使用封装
一共有三种封装方式:private public protected 请参考语言书
另外 如果你想让某个类能访问另一个类的内容 这时使用friend
在c++中,struct与class的功能是一样的 都可以有接口(函数) 所不同的是
struct 默认时是public class默认是private

3 继承
继承是进行类的具体化
如上面的衣服 有上衣与裤子 但是它们都有衣服的特征
所以可以共用衣服类内容 再定义自己特有的内容与接口 这也是一种代码复用
继承也有三种继承方式:private public protected 常用的是public 当然不要忘记还可以使用其它类型的继承方式


4 多态
多态就是实现的可替换性 又分成运行时多态与编译时多态
如果运行时才替换实现 叫运行时多态 如果编译时就已经知道使用哪个实现 叫编译时多态
实现多态的方法有:
方法的重载(function overload)同一个可见范围中 函数名相同 但是参数不同 这时不需要virtual
方法的覆盖(function override) 在有继承关系的类中 子类提供自己的实现对父类实现进行覆盖
注意这时 必须在父类中需要被覆盖的方法定义前加上virtual

5 this
this 使用于对象中 表示当前对象

6 虚函数与纯虚函数 抽象类
虚函数就是在函数定义前面有virtual的函数 表示它的实现可以被覆盖 也就是用于多态为的方法的覆盖
纯虚函数就是只定义不提供实现的函数 它前面有virtual 最后是=0 如下
class A{
public:
virtual void add() = 0;
};
这时add函数叫纯虚函数 它用于定义接口
有纯虚函数的类叫抽象类 如上就是类A 它不可以定义对象 当然可以定义对象指针指向子类

7 模板
模板就是使用template关键字定义的类或是方法 表示某类操作除了类型不同外 处理方法相同
参考语言书

8 RTTI(运行时识别)
运行时识别对象类型 或是进行对象的向上转换(从基类转换到子类 见dynamic_cast)


其中虚函数与纯虚函数是定义接口的方法 在设计模式中使用的比较多
如果你想让某个接口晚实现的话 就使用它们 理解它们对理解设计模式会有很大作用
 楼主| 发表于 2004-6-26 21:44:44 | 显示全部楼层
继承与组合
继承就是有父子关系的类

组合是把一些对象放在一起使用

继承破坏了封装性(子类可以看到父类的实现细节 父类实现的改变是很难的事情)所以优先使用组合

另外使用继承时 应该把析构函数定义成virtual的
虚析构函数保证子类被父类指针调用 并释放时可以正确析构
 楼主| 发表于 2004-6-26 21:49:27 | 显示全部楼层
设计模式的分类

根据模式的目的(用来完成什么工作的) 可以把设计模式分成:
创建型模式:
结构型模式:
行为型模式:

三种

创建型模式与对象的创建有关 结构型模式处理对象或类的组合 行为型模式对类和对象怎样交互和怎样分配职责进行描述

根据模式的作用范围(是处理类还是处理对象的) 可以分成
类模式
对象模式
两种

类模式处理类与子类的关系
对象模式处理对象间关系

创建型类模式将对象的部分创建工作延迟到子类 而创建型对象模式将它延迟到另一个对象中

结构型类模式使用继承机制来组合类 结构型对象模式描述了对象间的组装方式

行为型类模式使用继承描述算法与控制法 行为型对象模式则描述一组对象怎样协作完成单个对象无法完成的工作


总的类说 创建型模式就是怎样构造一个对象的方法
结构型模式就是怎样使用组合的方法
行为型则是怎样分配类或对象的功能 及怎样调用它们的算法

类模式与类继承相关 对象模式与对象间关系相关

明确了这些基本的功能后 后面看设计模式时会更清楚一点
 楼主| 发表于 2004-6-26 21:50:10 | 显示全部楼层
面开始按目的来看设计模式

第一个是创建型模式

上面说到创建型模式是为了怎样构造一个对象而产生的

创建型模式抽象了实例化过程 帮助一个系统独立于如果创建 组合和表示它的那些对象
类创建型模式使用继承改变被实例化的类 对象创建型模式将实例化托给另一个对象

在这些模式中有两个不断出现的主旋律
1 它们都将系统到底使用哪些具体类信息封装起来
2 它们隐藏了这些类的实例是如何被创建和放在一起的

整个系统关于这些对象知道的就是由抽象类定义的接口
(注意看到抽象类 也就是上面的原则中的针对接口而不是实现编程 使用抽象类可以把这个类的具体怎样实现放在子类中进行 而调用者只需要知道这个类有这样的功能就行了 举例如打印 调用者只要知道可以打印出来就可以 而不必知道是在屏幕上打印还是显示器上打印)

所以 创建型模式在什么被创建 谁创建它 它怎样被创建 及何时创建提供了很大的灵活性
创建型模式有如下五种


类创建型模式
1 工厂方法 factory method 定义一个用于创建对象的接口 让子类决定将哪一个类实例化
当你编译时不知道要实例化哪一个类 这时可以把类的创建放在子类中 提供专门的接口创建一个对象
在书中例子是application与document,application对不同的应用要使用不同的document,所以编译时不知道需要哪个 document子类 这时可以在application中提供createdocument接口 返回一个document对象指针
因为返回的是一个对象 所以叫工厂方法

对象创建型模式

2 抽象工厂abstract factory 提供一个创建一系列相关或是相互依赖对象的接口 而无需指定它们具体的类
如 界面的显示有不同的控件 如form button等 而这些控件都与具体的系统相关 也就是说 要使用其中一个就得和这组控件相配合
这时你定义一个抽象工厂类 把这些控件的构造都放在这个抽象工厂类中 当需要一个控件中 调用这个抽象工厂类提供的接口就可以了
但是 要怎样知道这些控件有什么功能呢 每个控件定义一个抽象类 声明它提供的功能
后面使用抽象类的指针来调用这个控件 问题解决
因为它像一个工厂一样生产出相似产品 而这些产品都是抽象类 所以叫抽象工厂




3 生成器builder 将一个复杂对象的构建与它的表示分离 使同样的构建过程可以创建不同的表示
builder模式有两个参与者 一个是生成器(builder) 负责生成新对象 另一个是导向器(director),
导向器分析转入的信息,处理后根据信息的内容调用生成器 生成器根据不同的信息内容生成不同的对象来保存这些信息
在书中是一个rtf文字阅读器 分析rtf模式文件后根据不同的信息创建不同的对象保存这些信息


4 原型prototype 用原型实例指定创建对象的种类 并通过拷贝这个原型来创建新的实合金

技术上的实现:根据一个已有的对象信息clone产生新对象

5 单件singleton,保证一个类只有一个实例 并提供访问它的一个全局访问点
这个技术没有什么难度的 就是需要把构造函数都定义成非public,只要构造函数非public就不可以被再构造 所以后面可以使用其它方面创建一个实例
书上使用静态变量与静态函数的方法来提供全局调用接口
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表