设计模式 Mixin (混入类)
混入(mix-in)类代表类之间的另一种关系。在C++中,混入类的语法类似于多重继承,但是语义完全不同。混入类回答"这个类还可以做什么"这个问题,答案经常以"-able"结尾。通过混入类,可以向类中添加功能而不需要保证完全的"是一个"关系。您可以把它当作一种分享(share-with)关系。
回到动物园示例,您可能想引入某些动物是可以"做宠物"这一概念。也就是说,有些动物可能不需要训练就可以作为动物园游客的宠物。您可能想让所有可以做宠物的动物支持"做宠物"行为。由于可以做宠物的动物没有其他的共性,因此您不想破坏已经设计好的层次结构,Pettable就是很好的混入类。
混入类经常在用户界面中使用。您可以说Image能够点击,而不需要说PictureButton类既是Image又是Button。您桌面上的文件夹图标可以是一个可以拖动的Image。软件开发人员总是喜欢弄一大堆有趣的形容词。
当考虑类的差异而不是代码的差异时,混入类以及超类的区别还有很多。因为范围有限,混入类通常比多重层次结构容易理解。Pettable混入类只是在已有类中添加了一个行为,Clickable混入类或许仅仅添加了"按下鼠标"以及"抬起鼠标"行为。此外,混入类很少会有庞大的层次结构,因此不会出现功能的交叉混乱。
重读《设计模式》之学习笔记(一)--混入类
作者在1.6.4提到了混入类,可是对它的描述却非常简单:混入类是给其他类提供可选择的接口或功能的类。它与抽象类一样不能实例化。混入类要求多继承。并给了一个如下的类图:

我觉得,混入类主要用在不同的类有部分相同的接口的时候。使用混入类不仅可以提高代码的重用性,还可以使相关的操作集中在一个类中而不是分散在各个类中,提高了代码的可维护性。
现在用一个简单的例子来说明混入类在代码可重用性方面的优点。
比如现在有一个个人财务处理系统,要对一个人每个月的收入和支出进行统计整理并以报表形式体现出来。我们可以分别给收入和支出写两个抽象类CIncome和CExpenditure。当然我们可以给这两个类分别添加一个CreateReport()的方法来生成各自的报表。类图如下:

这样的话,我们就得分别给这两个类都添加一个几乎一摸一样的CreateReport()方法的代码。但是,一旦我们报表的生成方法有改动,我们就必分别须去修改类CIncome和类CExpenditure中的CreateReport()方法的代码;如果我们又为该系统增加了自动发送报表的功能的话,我们不得不分别给类CIncome和类CExpenditure添加一个SendReport()的方法。这样做,不但浪费时间而且使代码的可维护性降低。在这个时候我们就可以添加一个混入类CReport。类图如下:

采用新的继承体系后,对报表的实现功能有任何改动或者增添什么功能,都不必修改类CIncome和类CExpenditure。使用混入类提高了代码的重用性和可维护性。(王朝网络 wangchao.net.cn)
缘起:《设计模式》P148
re-mix in CodePlex
http://remix.codeplex.com/
https://www.re-motion.org/blogs/mix/category/mixins
https://www.re-motion.org/blogs/team/category/mixins
Relative subject:
http://en.wikipedia.org/wiki/Extension_method
http://en.wikipedia.org/wiki/Marker_interface
Implementing Mixins with C# Extension Methods
http://www.zorched.net/2008/01/03/implementing-mixins-with-c-extension-methods/
js掺合模式(Mixin)
设计模式 Mixin (混入类)的更多相关文章
- python 混入类MixIn
写在前面 能把一件事情说的那么清楚明白,感谢廖雪峰的官方网站. 1.为什么要用混入类?(小白入门) 继承是面向对象编程的一个重要的方式,因为通过继承,子类就可以扩展父类的功能. step1: 回忆一下 ...
- Python 实践--混入类
Mix-in:混入类是一种Python程序设计中的技术,作用是在运行期间动态改变类的基类或类的方法,从而使得类的表现可以发生变化.可以用在一个通用类接口中. 在实践一个 解析XML文件的实践中,体会动 ...
- 设计模式之UML类图的常见关系
设计模式之UML类图的常见关系 本文来自转载 烧点饭博客 本篇会讲解在UML类图中,常见几种关系: 泛化(Generalization),依赖(Dependency),关联(Association), ...
- 设计模式之UML类图
在学设计模式的过程中经常碰到各式各样的UML类图.那些眼花缭乱的符号有什么含义呢? 类图含义 类图中的关系 从网上找来一张图作为实例 依赖关系:比如动物依赖氧气和水,这里如学生要依赖自行车.用虚线箭头 ...
- iOS 基于MVC设计模式的基类设计
iOS 基于MVC设计模式的基类设计 https://www.jianshu.com/p/3b580ffdae00
- django-rest-framework框架 第二篇 之Mixin扩展类
Mixin扩展类 ['列表操作','过滤','搜索','排序'] <一>:<1>创建项目: 配置 urls 主路由 配置model文件(举个例子,就以book为模 ...
- mixin 扩展类的装饰
1,步骤: 1,自定义装饰器 # 我们自定义的装饰器: def my_decorator_1(func): def wrapper(request, *args, **kwargs): print(' ...
- 北风设计模式课程---UML类图各符号含义
北风设计模式课程---UML类图各符号含义 一.总结 一句话总结: 用脑子,挺好记的:实线关系肯定比虚线重,箭头.三角形.菱形的关系肯定依次加重,三角形是继承和实现, 1.UML类图中 线+箭头 表示 ...
- 23种常用设计模式的UML类图
23种常用设计模式的UML类图 本文UML类图参考<Head First 设计模式>(源码)与<设计模式:可复用面向对象软件的基础>(源码)两书中介绍的设计模式与UML图. 整 ...
随机推荐
- switch-case参数类型
switch语句用法: 0. switch语句由一个控制表达式和多个case标签组成 1. switch控制表达式支持的类型有byte.short.char.int.enum(JDK5).String ...
- 如何为 setTimeout() 方法传参
现有如下JavaScript代码: function printApple(apple){ console.log(apple, "is a kind of healthy fruit&qu ...
- win7 下配置 java 环境变量
首先,你应该已经安装了 java 的 JDK 了,笔者安装的是:jdk-7u7-windows-x64 接下来主要讲怎么配置 java 的环境变量,也是为了以后哪天自己忘记了做个备份 1.进入“计算机 ...
- HTML - 键盘事件
Keyboard 事件 onkeydown: 在用户按下按键时触发. onkeypress: 在用户敲击按钮时触发. onkeyup: 当用户释放按键时触发. 示例 <!DOCTYPE html ...
- Eclipse清除SVN密码
1. Eclipse/Subclipse并不会记录用户名及密码, SVN密码是由SVN客户端(JavaHL or SVNKit)负责维持的 2. 可查看Eclipse的Preferences中SVN属 ...
- Asp.net Mvc4 基于Authorize实现的模块访问权限
在MVC中,我们可以通过在action或者controller上设置Authorize[Role="xxx"] 的方式来设置用户对action的访问权限.显然,这样并不能满足我们的 ...
- SQLite 入门教程(四)增删改查,有讲究
增删改查操作,其中增删改操作被称为数据操作语言 DML,相对来说简单一点. 查操作相对来说复杂一点,涉及到很多子句,所以这篇先讲增删改操作,以例子为主,后面再讲查操作. 一.插入数据 INSERT I ...
- C# gridview分頁導出excel
#region 导出Excel方法 //导出到Excel按钮 protected void btnExport_Click(object sender, EventArgs e) { Export(& ...
- Ojbect-C2 3、NSArray和NSMutableArray数组的使用
Adopted Protocols NSCoding encodeWithCoder: initWithCoder: NSCopying copyWithZone: NSMutableCopying ...
- iOS app闪退的一般原因
1.函数无限递归爆栈(表视图返回Cell和返回行高的方法互相调用)2.某对象无法解析某个方法(没做类型转换.或者代理没实现某个方法)3.访问了某个已经被释放的对象(ARC之后不太有)4.从Bundle ...