如何为具有组合的耦合类保存冗余计算

时间:2017-05-18 02:56:49

标签: python design-patterns

我有几个相互耦合的类,我希望有一个最小化冗余的设计。

目前设计如下。这些课程是

  • A
  • C,D
  • AC,AD:(A,C)和(A,D)的组合物

其中所有类都使用相同的数据进行初始化,每个类执行一些计算并保存自己的结果。更具体地,用户将创建A,AC,AD但不是C和D的实例。换句话说,对于用户,A,AC,AD是类似的事物并且具有统一的接口,而C和D是隐藏的。这里的逻辑是,例如,除非我们从中排除A的结果,否则C的结果没有用。一些模拟代码如下

class A(object):
    def __init__(self, data):
        # some work
    def postproc(self, *args):
        # some real work
        self.result = ..

class AC(object):
    def __init__(self, data):
        self.a = A(data)
        self.c = C(data)
    def postproc(self, *args):
        result_a = self.a.postproc(*args[:3])
        result_c = self.c.postproc(*args[3:])
        self.result = exclude_c_from_a(result_a, result_c)

使用当前设计,如果用户创建A和AC的实例(或AC和AD或其他组合),则A的计算会多次完成。我想没有多余的计算,应该如何改变设计?

关于用法的更多细节:将有多个具有不同初始数据的A实例。因此,我不能使用单例来保证只有一个A实例。

2 个答案:

答案 0 :(得分:1)

我最终使用了memoization作为解决方案。

def memoize(func):                                                                 
    """                                                                             
    Decorator for memoization. Note the func arguments need to be hashable.         

    @type func: a callable                                                          
    """                                                                             
    memo = func.memo = {}                                                                                                                                              
    @wraps(func)                                                                    
    def wrapper(*args):                                                             
        if args not in memo:                                                        
            memo[args] = func(*args)                                                
        return memo[args]                                                           
    return wrapper 

它可以修饰类定义

@memoize
class A(object):
    def __init__(self, arg1, arg2):
        ...

这样对于相同的输入参数,只创建一个实例。

答案 1 :(得分:0)

  

应该如何改变设计?

  1. 只需将A和C传递给AC的构造函数,这样就不必在构造函数中实例化A和C.
  2. 不要将数据传递给A的构造函数。相反,将结果传递给A的构造函数。除了设置依赖项之外,您应该阻止在构造函数中执行任何工作。
  3. 创建一个仅负责计算结果的类。