在python类中实现不断变化的业务逻辑

时间:2019-05-20 15:24:37

标签: python business-rules

我想在python中实现业务逻辑,其中更改经常发生。更新此业务逻辑应该很容易,并且应该保留旧的逻辑。

我当前的想法如下:

class Item():
    def __init__(self):
        pass        

    def __call__(self, company, time):
        if time < "2017Q1":
            return self.calc_base(company, time)
        elif time < "2018Q2":
            return self.calc_after2017Q1
        else:
            return self.calc_after2018Q2

    def calc_base(self, company, time):
        return income(company, time) + costs(company, time)

    @time_after("2017Q1")
    def calc_after2017Q1(self, company, time):
        intermediate = self.calc_base(company, time)
        return max(intermediate, 100_000) #Haircutt due to article xxx

    @time_after("2018Q2")
    def calc_after2018Q2(self, company, time):
        intermediate = self.calc_after2017Q1(company, time)
        intermediate -= 20_000 #Correction due to xxx

这个想法是用一个公司和一个时间作为参数来调用这个类的一个实例。在内部,该类将查看当时要使用的业务逻辑,并将路由到正确的计算功能。每当逻辑更改时,只需添加一个新功能并记录其与以前的计算有何不同。

此实现需要在self。 call 函数中使用if .. elif .. else进行一些内部整理。谁能想到自动化的pythonic智能方法?我一直在考虑装饰器的路线(如本示例中所述,但未实现),在这里我可以指定从新逻辑的哪个时间有效直到下一个逻辑被取代为止。

最后,我觉得我在这里重新发明轮子,因为这可能是一个非常标准的问题。但是我似乎以某种方式缺乏正确的词汇来在这个方向上找到好的结果。因此,我也希望能向正确的方向提供提示。

1 个答案:

答案 0 :(得分:1)

更多的OOP方法将是具有一个抽象类来定义基本calc函数。创建After201Q1作为从该抽象类扩展并实现calc函数的类。然后创建After2018Q2作为从After201Q1扩展的类,然后编写一个factory函数以基于该时间获得实现。我不认为比较时间少于字符串是正确的方法。我认为,直接建立索引是正确的方法。我创建了一个示例代码。该代码通常看起来像下面的代码。但是,您可能需要根据需要进行少量修改。但是我已经展示了一个基本的想法。


from abc import ABC, abstractmethod
from collections import OrderedDict


def income(*args):
    return 1


def costs(*args):
    return 2


# Abstract class
class Item(ABC):

    def calc_base(self, company, time):
        print('Base calc_base')
        return income(company, time) + costs(company, time)

    def calc(self, company, time):
        print('Base calc')
        intermediate = self.calc_base(company, time)
        return self.calc_specific(intermediate, time)

    @abstractmethod
    def calc_specific(self, company, time):
        pass


class After2017Q1(Item):
    def calc_specific(self, company, time):
        print('Running After2017Q1')
        return max(company, 100000)  # Haircutt due to article xxx


class After2018Q2(After2017Q1):
    def calc_specific(self, company, time):
        print('Running After2018Q2')
        intermediate = super().calc_specific(company, time)
        return intermediate - 20000


def factory(time):
    object_factory = OrderedDict([
        ('2017Q1', After2017Q1()),
        ('2018Q2', After2018Q2())
    ])
    return object_factory[time]


print(factory('2017Q1').calc(None, None))
print('-'*20)
print(factory('2018Q2').calc(None, None))



您可以添加任意数量的子类,仅编写calc_specific函数,然后将其添加到factory函数中,以便将基于时间值调用它。