• 一个一对多问题的设计模型


        问题引入:

            今天在做一个用来限制对象位置的功能类,要完成的任务就是当对象被拖动的时候,不允许超出工作区域多少距离。这个问题不好处理的地方就是这个工作区域的获取问题,因为无法知道工作区域发生更改,并且工作区域更改的地方也无法直接设置给对象,即使能设置,也无法设置给这么多对象。因此这就是一个简单的一对多问题,即一个变化需要引起多个的变化。

        问题引出:

           简化一下上述问题。有一个对象CSample,其内部有一个属性miCount需要根据一个系统相关的属性miSystemValue来进行计算。在无法直接接收到这个系统属性发生更改的前提下,如何让其所有实例化出来的对象都能重新进行计算呢?(注:下面的代码没进行编译,随便写了下例子方便说明。)

    class CSample
    {
    	public:
    		CSample();
    		~CSample();
    
    		int GetCount()
    		{
    			return miCount;
    		}
    
    	protected:
    		MakeCount(){miCount = miValue + miSystem;}
    
    	private:
    		int miCount;
    		int miValue;
    		int miSystem;   // 系统所提供的一个参数,全系统都唯一的
    }
    
    int main()
    {
    	CSample loSample1;
    	CSample loSample2;
    	CSample loSample3;
    
    	cout << loSample1.GetCount << endl;
    	cout << loSample2.GetCount << endl;
    	cout << loSample3.GetCount << endl;
    	
    
    	// 假设这时候miSystem发生了变化
    	// 如何让上述三个对象重新计算其内部的miCount的值?
    	
    	return 0;
    }


        解决办法:

    1、主动索取方式。

            所有实例化出来的对象,每次在计算的时候都直接主动去获取系统的这个参数,这样不管多少个实例,系统参数如何改变都能保证正确。假如GetSystemValue是获取系统参数的函数,则只需写成miCount = miValue + GetSystemValue()即可。

        好,下面问题来了。

            1、如果无法直接获取到系统参数怎么办?

            2、如果这种计算效率很低,要求优化,怎么办?

            问题1是这个方法最不好解决的地方,因为这个方法就是假设能直接获取的基础上,这里提出这个问题是方便后面的方法能考虑到这个问题。问题2有一定的优化方式,就是自己记住旧的系统参数,每次进行计算前进行判定需不需要重新计算,这样能避免每次都无厘头的进行计算,但是效率效果还不是很好。

    2、提供静态函数。

             类的静态函数只能操做静态变量,因此系统参数作为静态变量存储在类内部,所有实例化的类共享这个变量,注意要传进去类的实例化指针,才能操纵非静态成员变量。这里是重新计算miCount值。

          对于上面提到的两个问题,这种方式都比较好的进行了解决。但是这中方法有个缺陷就是在获取到系统参数更改的地方,必须拥有所有实例化的对象指针,不然如何在这里调用这个静态函数的同时传入对象指针呢?因此,问题3来了。

          如果实例化的对象位置无法预知,怎么办?

    3、提供一个管理器。

            上述3个问题,要想同时解决,那么需要满足的条件有:类需要提供函数去被动触发进行计算,不能任何时候都计算,以及需要将所有实例化的对象集中起来进行管理。一种好的解决方式是,提供一个全局的容器,在对象的构造函数内主动加入到容器中去,当系统参数发生更改的时候,遍历容器去调用触发计算的接口。

             后记:本来看起来很简单的一个功能,在实际实现的时候才发现因素导致很多方法不适用,其实归根到底就是程序灵活性的问题。

    友情提示: 写个博客对于我来说不容易,如果此文是我原创,烦请转载加个链接http://www.cnblogs.com/monotone/。谢谢。
  • 相关阅读:
    统计学(第六版)14单元——学习总结
    统计学(第六版)13单元——学习总结(时间序列分析总结)
    统计学(第六版)11到12单元——学习总结
    Kubernetes: 微内核的分布式操作系统
    彻底搞懂JavaScript之原型
    手把手带你玩转k8s-一键部署vue项目
    新一代缓存Caffeine,速度确实比Guava的Cache快
    理解 Es6 中的 Symbol 类型
    一天一大 leet(用两个栈实现队列)难度:简单 DAY-30
    (Java 源码阅读) 春眠不觉晓,HashMap知多少
  • 原文地址:https://www.cnblogs.com/monotone/p/2770596.html
Copyright © 2020-2023  润新知