singleCall单来源调用解析及实现
来源:互联网 发布:头影测量软件 编辑:程序博客网 时间:2024/04/26 13:21
出处:http://www.cnblogs.com/lang5230/p/5768292.html
定义:
单来源调用指一个类的生成工作只能由特定类来执行。
eg李宁牌鞋子只能由李宁专卖店生产
这个问题归结起来,也就是说在工厂模式中,指定的产品类只能通过具体的特定工厂类来生成,而不能自己new出来或者通过其他类生成。
具体的,我们就在代码实现中进行说明了。
这里我们来一步一步分析。
首先,一个类实例(对象)不能自己产生,那么。我们就需要屏蔽构造函数了。
那么,屏蔽了构造函数之后,如何获取一个实例呢。
有两种方案可以实现。
方案一:
通过继承获取构造函数执行权限。如代码
class base{protected: base() { Trace(""); }};class driver:protected base{public: void test() { base b; }};int main(int argc, char const *argv[]){ driver d; d.test(); return 0;}
这个方案只是可以让一个类能够产生实例。单他和我们的意图严重偏离:
a实例和子类的生命周期一致。
b没有自主权。
c其他类也可以模拟他的实现,继承父类获取生成权,这显然是个垃圾方案。
方案二:类似单例模式方法处理
产品类 构造函数屏蔽,但是提供一个获取实例的共有方法
静态方法获取实例class base{protected: base() { Trace(""); }public: static base* getInstance();};base* base::getInstance(){ return new base();}int main(int argc, char const *argv[]){ // base* p = new base(); base * p = base::getInstance(); return 0;}
通过方案二,我们实现了一个类不能自己执行 base *p = new base()
类型绑定
那么下面我们的目标就是将这个产品类和具体可生产者进行绑定了。
如何绑定呢,对于一个特定的类,处理之,我们就想到了this指针
所以我们要做的就是,产品类构造函数依赖工厂类的this 指针
// 通过静态方法获取,且依赖driver的this指针。// 但是此时也可以通过临时对象driver生成class driver;class base{protected: base()//driver*) { Trace(""); }public: static base* getInstance(driver*);};base* base::getInstance(driver*){ return new base();}class driver{public: base* getInstance() { return base::getInstance(this); }};int main(int argc, char const *argv[]){ base * p = (driver()).getInstance(); //我们所期望的运行方式。 p = base::getInstance(new driver()); //产品类抓住漏洞强行生成自我 return 0;}
到这里,貌似我们的目标已经达到了,但是呢。如例子中的 p = base::getInstance(new driver());这个方法,本质还是base类自主生成的。
并不能符合我们的要求。
那么到这里,我们应该如何处理呢。
我能想到的就是,不光让base建立依赖driver的this指针,同时设置权限。才能执行getinstace()
首先给出最终代码了
// 抽象接口类,提供子类行为,同时定义权限值以及权限判断给base中的getinstace方法使用class abstractDriver{protected: bool _canCreate; abstractDriver(bool can) :_canCreate(can) {}public: virtual bool canCreate(){ return _canCreate; }};class base{protected: base() { Trace(""); }public: static base* getInstance(abstractDriver*);};// 根据依赖的this对应类是否有权限执行决定生成base* base::getInstance(abstractDriver*dr){ if (dr->canCreate()) /* code */ return new base(); else return NULL;}class driver:public abstractDriver{public: driver() :abstractDriver(false) { Trace(""); } //在获取base实例前后修改权限。保证外部权限始终伪假 base* getInstance() { _canCreate = true; base* p =base::getInstance(this); _canCreate = false; return p; }};int main(int argc, char const *argv[]){ base* p = base::getInstance(new driver()); cout << p <<endl; //NULL,未生成实例 p = (driver()).getInstance(); cout << p <<endl; p = (driver()).getInstance(); cout << p <<endl; return 0;}
好了,最终的实现版本就完成了。
符合我们的目标
base类只能通过driver类生成。
最后,我们可以发现,这个实现中的getInstace方法让我们想到了单例模式的实现。
不同的是单例模式的结果是最终
a只有一个类型实例产生,
b生成方式可以是自主的 base::getinstance()
而我们的单来源调用,
a。生成实例个数不一定是一个,只是生成方式限定了
b。不能通过直接调用base::getinstance()生成。
之所以拿出来将两个模式进行比较,是因为:单来源调用并不是23种设计模式中的一种,初次看他时,我自己也是一脸蒙蔽。其次,两者都是很重要,很常用的方法。
- singleCall单来源调用解析及实现
- 外国英文名字大全及解析——姓氏来源
- WinDbg+Rotor解析WinForm调用堆栈及实现
- SimpleJson解析及调用
- WEB服务动态解析及调用技术的实现(基于WSDL4J及SAAJ)
- hadoop单节点安装及eclipse调用
- javaGUI编程中JFrame对象调用的add()函数的作用及来源
- Spring 源码解析错误来源
- 单例模式代码实现与解析
- 面试常客,单例模式实现解析
- 实现循环调用系统的震动或者单次调用
- 英文名字来源及涵意!
- 创意来源及网站规划
- 系统调用的实现及调用过程
- shell自定义函数及参数调用解析
- 接口的调用及xml的解析
- dedecms调用单页内容,及首页调用单页内容
- 通讯录调用及委托实现
- Maven学习总结
- 操作系统学习_Linux0.12_as汇编
- CCF CSP认证考试历年真题 日期计算 C语言实现
- 喜大普奔!程序员已当选最佳国民女婿
- python unicode转str
- singleCall单来源调用解析及实现
- Manifest merger failed :
- html的localstorage的存储应用
- Access denied for user 'root'@'localhost' (using password:YES)解决方法
- Spring Boot JPA 连接数据库
- php define与const的区别
- 常见数据结构应用场景
- NIo、Bio、aio、 的原理及区别与应用场景
- 代理属性为何要用 weak 修饰?