zoukankan      html  css  js  c++  java
  • 使用function改进设计

      我们假设这样一种应用场景,有两个类A和B,在B中需要调用A的一个方法(成员函数)。那么我们的代码可能是这个样子的:

    class A
    {
    public:
    	void Func(void) 
    	{ 
    		printf("%s\r\n", __FUNCTION__); 
    	}
    };
    
    class B
    {
    public:
    	void UseA() 
    	{ 
    		a->Func(); 
    	}
    
    public:
    	A* a;
    };
    

      调用代码是这样的:

    A a;
    B b;
    b.a = &a;
    b.UseA();
    

      我们观察上面的代码,看看有什么问题:

    1. 两个类中B对A产生了一个依赖关系,这让人有点不爽;
    2. 哪天我们想用另外一个类C替代A的作用意味着我们要重写B,这让人更不爽;
      上面两个问题实质上是耦合的问题,依赖关系是强耦合,耦合度高了代码可读性和可维护性都会变差。
     
      我们分析一下这两个类的关系,在B中调用了A的一个成员函数所以产生了依赖。而这个调用完全可以使用函数指针,由于C++的函数指针使用起来太过麻烦,所以我们用function代替。改进后的B的定义如下:
    class B
    {
    public:
    	std::function<void(void)>	AFunc;
    
    	void UseA(void) 
    	{ 
    		if(AFunc != NULL) AFunc(); 
    	}
    };
    
     
    调用方法和之前差不多,只是把赋值操作的对象由A的指针改成了A的成员函数:
    A a;
    B b;
    b.AFunc = std::bind(&A::Func, &a);
    b.UseA();
    
      
      代码看起来复杂了那么一点点,但是从代码逻辑的角度看改进了很多:
    1. B和A彻底解耦,只在运行期才B的某个对象对A的某个对象产生依赖,而且这种依赖完全在调用者的控制之下;
    2. 我们想把A替换成C,那么就换把,改一下调用代码就可以搞定,B的定义代码一行不动——这正是我们追求的灵活性和扩展性;
    C c;
    b.AFunc = std::bind(&C::Func, &c);
    b.UseA();
    
     
      
      作为C++ 0x的新特性,std::function和std::bind目前只在VS2010中才被支持,用其他编译器的同学可以用boost库作为替代方案,用法完全相同。
    作者:小时了了
    原创文章,欢迎转载,但请以链接形式注明本文地址.
  • 相关阅读:
    保险行业电话外呼型呼叫中心方案
    12355青少年服务台呼叫中心解决方案
    未能找到类型集或命名空间名称 "xxxxxx" (是否缺少using 指令或引用?)
    Smarty中section的使用
    什么是Asterisk,它如何帮助我们的呼叫中心?
    高效呼叫中心的8个健康工作习惯
    Python 爬起数据时 'gbk' codec can't encode character 'xa0' 的问题
    Python 网页解析器
    Python 爬虫入门3种方法
    Python open 读写小栗子
  • 原文地址:https://www.cnblogs.com/xrunning/p/1897575.html
Copyright © 2011-2022 走看看