- 论坛徽章:
- 3
|
转自 http://avboost.com/t/void/468
工作中,可能经常需要使用 “工厂” 模式。用工厂创建一个对象,然后使用基类指针返回给调用者。
调用者则使用虚函数来访问他们。
在 C 里,工厂模式的实现需要使用 void* , 在工厂对象里,把 一个叫 private 的 void* 转成自己内部的格式,来保存和使用内部数据。
void * 是邪恶的, 虚函数也是邪恶的。这些所谓的 OO 造成了巨大的思维负担。因为表明上看,工厂创建的对象和程序主题脱离了耦合,实际上,工厂创建的对象必须继承自主程序里定义好的类型。这难道不是最大的耦合么? 而且如果主程序里定义好的基对象变了,那么所有的工厂对象都得修改。实在是一个看似低耦合实际上高耦合的设计。
现在,有一个新的模式来解决:使用 std::function 。
让我们看一个例子,当然这个代码是简化版
- class file_source{
- public:
- virtual read(..);
- virtual write(...);
- };
- // 某工厂类型
- class bt_file_source : public file_source
- {
- 巴拉巴拉
- };
- // 某工厂创建代码
- file_source * open_uri(...)
- {
- if( uri 是 BT 链接)
- return new bt_file_source( ...... );
- }
复制代码 这种代码看似接触了工厂对象和主程序的耦合,实际上使得工厂对象被主程序强烈的耦合了。工厂对象自身的复用性非常低下。
那么看一下 std::function 的介入会怎么样?- // 这里没写 function 里面的参数,不是没有,而是没写出来
- class file_source{
- public:
- std::function<> read;
- std::function<> write;
- };
- // 某工厂类型
- // 注意这里,没有任何的继承
- class bt_file_source
- {
- // 这里没写参数,不是没有,而是没写出来
- read();
- write();
- };
- // 某工厂创建代码
- // 看,返回值都不用指针了,消灭指针!
- file_source open_uri(...)
- {
- file_source source;
- if( uri 是 BT 链接)
- {
- auto bt_file_sourceptr = make_shared<bt_file_source>( xxx 参数们);
- source.read = bind(&bt_file_source :: read , bt_file_sourceptr, _1,_2 , ... 其他占位们 );
- source.write = bind(&bt_file_source :: write , bt_file_sourceptr, _1,_2 , ... 其他占位们 );
- }
- return source;
- }
复制代码 可以看到,这次工厂模式,工厂对象彻底和主程序脱离耦合,工厂对象也可以自由的被复用。
而且调用方使用的是对象,而不是指针来访问需要的功能,这意味着调用方省去了指针管理方面的复杂度。
通过智能指针作为 bind 的对象参数, 保证调用方的 source 代理对象(和他的很多副本,因为他是个对象,而且还能拷贝)被撤销后,bt_file_source 对象和会被正确的释放。
转自 http://avboost.com/t/void/468 |
|