OOD沉思录 --- 类和对象的关系 --- 包含关系2
4.6 尽量让类中定义的每个方法尽可能多地使用包含的对象(即数据成员)
这其实就是高内聚的翻版强调。如果每个类的情况并非如此,那很可能是这一个类表示了两个或更多的概念,记住一个类只应该表示一个概念。
最明显的情况就是类的一半方法使用了一半的数据成员,而另一半方法使用了另一半的数据成员,那么这个类就应该一分为二。
我们假设一个澡堂,有VIP客户和普通客户,各自有不同的服务(普通客户享受中专生服务,VIP客户享受大学生服务),则定义如下:
- class 澡堂
- {
- stack<中专生> 普通服务员;
- stack<大学生> VIP服务员;
- 普通接待()
- {
- 普通服务员.Pop().侍候();
- }
- 普通结帐()
- {
- 普通服务员.Pop().结帐();
- }
- Vip接待()
- {
- VIP服务员.Pop().侍候();
- }
- VIP结帐()
- {
- VIP服务员.Pop().结帐();
- }
- }
这是一个我经常看到的类似结构,这种结构不可避免地会在使用者的代码里进行很多条件判断,来确定到底调用那个版本的方法,而这种判断最好避免。
原因在于这一个类包含了两个概念,一个是针对普通客户,一个是针对VIP客户,违反了本条原则,我们应当将其分开,这里可以考虑再次抽象
- class 澡堂
- {
- abstract 接待();
- abstract 结帐();
- }
- class 普通澡堂:澡堂
- {
- stack<中专生> 服务员;
- 接待()
- {
- 服务员.Pop().侍候();
- }
- 结帐()
- {
- 服务员.Pop().结帐();
- }
- }
- class VIP澡堂:澡堂
- {
- stack<大学生> 服务员;
- Vip接待()
- {
- 服务员.Pop().侍候();
- }
- VIP结帐()
- {
- 服务员.Pop().结帐();
- }
- }
这样这个类的使用者可以使用如下方法:
- 澡堂 tmp=null;
- if(顾客 is 普通客户)
- tmp=new 普通澡堂();
- if(顾客 is VIP客户)
- tmp=new VIP澡堂();
- tmp.接待();
- //......
- tmp.结帐();
眼神好的可能马上就会提出,这里也进行了判断,但是这里的判断我们可以通过两种手段来处理
一,字典
在外部保存一个字典:Dictionary<顾客类型,澡堂> dic; 那么上面的代码就成为下面这样:
- 澡堂 tmp=dic[顾客类型];
- tmp.接待();
- //......
- tmp.结帐();
二,简单工厂
实现一个简单工厂,澡堂Factory,则使用代码如下:
- 澡堂 tmp=澡堂Factory.Create(顾客类型);
- tmp.接待();
- //......
- tmp.结帐();
这两种方式都可以在程序配置的时候进行调整,将类型的依赖延迟到配置细节中(而这正是类型注入的要旨,别被那些专有的很玄的框架名次忽悠,其实就是这么简单)。
OOD沉思录 --- 类和对象的关系 --- 包含关系2的更多相关文章
- OOD沉思录 --- 类和对象的关系 --- 包含关系1
4.5 如果类包含另一个类的对象,那么包含类应当向被包含的对象发送消息(调用方法). 也就是说,所有的包含关系都应当是使用关系. 如果不是这样,那么包含的类有什么用处呢?当然,面向过程的开发人员会想 ...
- OOD沉思录 --- 类和对象的关系 --- 包含关系4
4.9 在实现语义约束时,最好根据类定义来实现.但是这经常会导致泛滥成灾的类,在这种情况下约束应当在类的行为中实现,通常在类的构造函数中实现,但不是必须如此. 还是以汽车为例,我们看汽车的定义,为了集 ...
- OOD沉思录 --- 类和对象的关系 --- 包含关系3
4.7 类包含的对象数目不应当超过开发者短期记忆数量,这个数目通常应该是6左右 4.8 让系统在窄而深的包含体系中垂直分布 假设有如下两份菜单: 正餐 --->甜瓜 --->牛排 ---& ...
- OOD沉思录 --- 类和对象的关系 --- 使用关系
使用关系 对象A的方法MethodA使用了B的方法MethodB,则表示A对B存在使用关系 使用关系的最关键问题在于,A如何找到B,存在6种方案 方案一: A包含了B,B作为一个成员定义在A的类中,那 ...
- OOD沉思录 --- 类和对象的关系 --- 使用关系原则
4.1 尽量减少类的协作的数量,即减少使用者和被使用者的数量. 协作意味着一定程度的耦合,但是完全没有协作的类也是没有意义的,最多只能作为一个库使用. 通过抽象,依赖接口,可以最大程度减少依赖的实现类 ...
- php课程 11-37 类和对象的关系是什么
php课程 11-37 类和对象的关系是什么 一.总结 一句话总结:类生成对象,对象是类的实例化,一定是先有类,后有对象,一定是先有标准,再有个体. 1.oop的三大优势是什么? 重用性,灵活性.扩展 ...
- OC学习--类和对象的关系
1. 如何创建对象 面向对象解决问题的时候必须有对象, 那应该如何创建对象? 以建造汽车为例子来解释: >建造汽车需要造车图纸, 图纸上 清楚的描述出 汽车具备的属性和功能(行为) >属性 ...
- Java面向对象(概述,构造函数,类与对象的关系,this关键字,成员、局部),匿名对象的调用,构造代码块(5)
Java面向对象(概述,构造函数,类与对象的关系,this关键字,成员.局部),匿名对象的帝爱用,构造代码块(5)
- 2.java面向对象类与类/类与对象之间关系详解
继承.实现.依赖.关联.聚合.组合的联系与区别 下面的内容很基础,同时也很简单,但是也很重要. 继承 指的是一个类(称为子类.子接口)继承另外的一个类(称为父类.父接口)的功能,并可以增加它自己的新功 ...
随机推荐
- 基于Redis的BloomFilter算法去重
BloomFilter算法及其适用场景 BloomFilter是利用类似位图或者位集合数据结构来存储数据,利用位数组来简洁的表示一个集合,并且能够快速的判断一个元素是不是已经存在于这个集合.因为基于H ...
- LeetCode-Maximum Product of Word Lengths
Description: Given a string array words, find the maximum value of length(word[i]) * length(word[j]) ...
- C#设计模式——组合模式(Composite Pattern)
一.概述 在软件开发中,我们往往会遇上类似树形结构的对象体系.即某一对象既可能在树形结构中作为叶节点存在,也可能作为分支节点存在.比如在文件系统中,文件是作为叶节点存在,而文件夹就是分支节点.在设计这 ...
- MIME(Multipurpose Internet Mail Extensions)的简介
多用途互联网邮件扩展类型(MIME) 作用:用于标识Web资源类型(Multipurpose Internet Mail Extensions,MIME) 效果:Web上MIME为每种类型的资源提供一 ...
- sencha 报错问题汇总
store的url必填 否则报错:Uncaught TypeError: Cannot read property 'indexOf' of undefined ext-all.js store必须在 ...
- BI之SSAS完整实战教程4 -- 部署至SSAS进行简单分析
上一篇已经创建了多维数据集的结构. 接下来我们将多维数据集的架构定义发送到Analysis Services实例,部署到AS上去. 文章提纲 部署和浏览多维数据集 SSMS使用简介 总结 一.部署和浏 ...
- 关于SVN删除后的文件不能重新添加(正常途径不行)
在你自己的机器上(即SVN客户端),把“新建test”文件夹标记为删除,然后提交,在删除之前可以备份“新建test”文件夹,提交后,在当前文件夹下更新SVN.然后把你刚刚备份的文件夹重新放到该目录下. ...
- 【C#进阶系列】00 序
老早就被各种推荐<CLR via C#>这本书了,然而一直没去学. 因为工作中所需要的.NET功底目前算是足以应付了,而前端却不熟,所以跑去学了一段时间前端的知识. 终于算是把前端方面的基 ...
- 重新想象 Windows 8 Store Apps (64) - 后台任务: 开发一个简单的后台任务
[源码下载] 重新想象 Windows 8 Store Apps (64) - 后台任务: 开发一个简单的后台任务 作者:webabcd 介绍重新想象 Windows 8 Store Apps 之 后 ...
- 关于html标签和属性的基本理解
一.关于标签和属性的基本理解: html页面的内容主要由"元素"或"标签"组成.使用标签来描述网页的内容. 标签tag一般都是成对出现,开始标签和结束标签,或者 ...