V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
yagamil
V2EX  ›  Python

需求里充斥着大量条件判断,有什么好的设计模式,便于后期维护的? 之前记得重构那本书里面是每个判断写成一个类

  •  1
     
  •   yagamil · 2021-04-01 22:31:11 +08:00 · 6361 次点击
    这是一个创建于 1314 天前的主题,其中的信息可能已经有所发展或是发生改变。

    需求里面这样的,这些变量是由用户填写的,所以也不能根据自己的想法吧冗余的合并了,而且用户自己填错没有执行到判断,这个是用户自身问题,也不做提示。

    不同的字母代表不同的值,当然可以设置为一样的
    T1 分钟内涨幅≥A1 且 起始涨幅> B1 则买入后 S1 分钟卖出,
    T2 分钟内涨幅≥A2 且 起始涨幅< B2 则买入后 S2 分钟卖出,
    T3 分钟内跌幅≥A3 且 起始涨幅> B3 则买入后 S3 分钟卖出,
    T4 分钟内跌幅≥A4 且 起始涨幅< B4 则买入后 S4 分钟卖出,
    
    T5 分钟内 C5≤涨幅< A5,且 起始涨幅< D5,则买入后 S5 分钟卖出
    T6 分钟内 C6≤涨幅< A6,且 起始涨幅> D6,则买入后 S6 分钟卖出
    T7 分钟内 C7≤跌幅< A7,且 起始涨幅> D7,则买入后 S7 分钟卖出
    T8 分钟内 C8≤跌幅< A8,且 起始涨幅< D8,则买入后 S8 分钟卖出
    
    35 条回复    2021-04-08 16:11:41 +08:00
    DTCPSS
        1
    DTCPSS  
       2021-04-01 22:36:37 +08:00   ❤️ 1
    表驱动?
    turan12
        2
    turan12  
       2021-04-01 22:43:39 +08:00 via iPhone
    这是量化交易系统的条件判断?
    abersheeran
        3
    abersheeran  
       2021-04-01 22:46:07 +08:00
    任何形式都不能去除最基本的 if else 判断。你只能隐藏它们。
    xx6412223
        4
    xx6412223  
       2021-04-01 22:46:22 +08:00 via Android   ❤️ 1
    没记错的话,应该是责任链模式,
    mmdsun
        5
    mmdsun  
       2021-04-01 22:50:40 +08:00 via Android
    适合用规则引擎做?
    skymei
        6
    skymei  
       2021-04-01 22:52:05 +08:00
    责任链模式或者策略模式
    yagamil
        7
    yagamil  
    OP
       2021-04-01 22:54:04 +08:00
    @turan12 是的,用户就是提出这样的需求。后期也可能回新增条件。
    yagamil
        8
    yagamil  
    OP
       2021-04-01 23:03:05 +08:00
    @abersheeran 是的,尽量避免嵌套大约 3 层的 if else,加上后期维护。
    cmdOptionKana
        9
    cmdOptionKana  
       2021-04-02 00:26:10 +08:00
    感觉这种没有规律且不受控制的(客户随时提出改动的)条件,用 if else 写死就很好,反正一共也没几行。

    当客户提出的情况越来越复杂,多数情况下都可以进行分类处理,但每个类别里面基本上也是写死几种特殊情况。
    andj4cn
        10
    andj4cn  
       2021-04-02 00:32:59 +08:00 via Android
    pipeline
    billlee
        11
    billlee  
       2021-04-02 00:46:31 +08:00
    如果是需要由运营人员随时改动的,还是适合做成规则引擎配置化

    如果钱给得不够做不了规则引擎,那还是 if ... else 吧,更好维护。这种需求搞一堆类才是无法维护的。
    akira
        12
    akira  
       2021-04-02 00:51:16 +08:00   ❤️ 3
    这其实就只有 2 个规则呀
    bugmakerxs
        13
    bugmakerxs  
       2021-04-02 00:58:52 +08:00 via Android
    责任链
    GeruzoniAnsasu
        14
    GeruzoniAnsasu  
       2021-04-02 04:00:19 +08:00
    啊? 规则是使用者定义的,你为什么想要 build in 到系统里?

    难到不是应该实现一个 parser 然后就把你展示的这段文本作为配置输入吗
    laike9m
        15
    laike9m  
       2021-04-02 07:39:06 +08:00
    没懂为什么需要设计模式
    turan12
        16
    turan12  
       2021-04-02 07:54:38 +08:00 via iPhone
    @yagamil 以前碰到过一个决策树系统,和这个很类似,在使用过程中这些条件肯定是需要频繁修改的。当时的做法是直接把条件语句写入数据库,并指定执行优先级。需要时直接 order by 以后读取执行即可。
    Mithril
        17
    Mithril  
       2021-04-02 08:08:10 +08:00
    做成规则引擎,而且你这就是简单的 if else,很好做。弄个 JSON 配置文件直接读进来当表判断就行了。
    然后剩下的都是 PM 和策划的活了。反正它们自己写的配置搞成死循环了也不关你的事。
    xinhaiw
        18
    xinhaiw  
       2021-04-02 08:11:25 +08:00
    反射
    gouflv
        19
    gouflv  
       2021-04-02 08:33:52 +08:00 via iPhone
    如果只是这几种情况,做可视化都可以了
    JJstyle
        20
    JJstyle  
       2021-04-02 08:36:42 +08:00 via iPhone
    写成配置,然后反解析
    yagamil
        21
    yagamil  
    OP
       2021-04-02 08:43:52 +08:00
    @turan12
    @akira
    @billlee
    @cmdOptionKana 谢谢大家。
    最后觉得就类的方式,每个决策做成一个类,主要为了后期维护方便

    ```
    class BaseStrategy():
    def __init__(self,
    strategy_number=None,
    monitor_time=None,
    monitor_raise_min=None,
    monitor_raise_max=None,
    start_raise=None,
    sell_time=None,
    ):
    self.monitor_time = monitor_time,
    self.monitor_raise_min = monitor_raise_min,
    self.monitor_raise_max = monitor_raise_max,
    self.start_raise = start_raise,
    self.sell_time = sell_time,
    self.strategy_number = strategy_number

    def valid(self):
    return True if self.monitor_time else False

    def match_time(self, current):
    return True if current >= self.monitor_time else False

    def get_sell_time(self):
    return self.sell_time

    def start_raise_condition(self, v_value):
    if self.strategy_number % 2 == 0:
    return True if self.v_value < self.self.start_raise else False
    else:
    return True if self.v_value > self.self.start_raise else False

    def meet(self, current, interval_raise_val, start_raise_val):
    if self.valid() and self.match_time(current) and self.interval_raise(interval_raise_val) and self.start_raise_condition(start_raise_val):
    return self.get_sell_time()
    else:
    return None



    class StrategyCondition1(BaseStrategy):

    def interval_raise(self, v_value):
    return True if self.v_value >= self.self.monitor_raise_max else False


    class StrategyCondition2(BaseStrategy):

    def interval_raise(self, v_value):
    return True if self.monitor_raise_min <= self.v_value < self.self.monitor_raise_max else False
    ```
    shyrock
        22
    shyrock  
       2021-04-02 08:59:09 +08:00
    规则引擎就是适配这种需求的。
    如果你的规则希望直接由业务人员定义,而且需要灵活变更规则,那么规则引擎比内置的设计模式要合适。
    zhuweiyou
        23
    zhuweiyou  
       2021-04-02 09:55:22 +08:00
    更倾向于做 parser
    guyeu
        24
    guyeu  
       2021-04-02 10:18:18 +08:00
    万事不决 DSL
    annielong
        25
    annielong  
       2021-04-02 12:16:30 +08:00
    那就是一个设计器,最后根据条件生成判断,
    matrix67
        26
    matrix67  
       2021-04-02 12:29:27 +08:00
    pancl
        27
    pancl  
       2021-04-02 12:39:09 +08:00 via Android
    写表
    shm7
        28
    shm7  
       2021-04-02 13:07:10 +08:00 via iPhone
    规则本身很规范的话,批量处理规则就成为了肯能
    1more
        29
    1more  
       2021-04-02 13:14:29 +08:00 via iPhone
    规则引擎或者 groovy 脚本引擎,后期维护事实和规则就行
    cubecube
        30
    cubecube  
       2021-04-02 15:05:33 +08:00
    不要用责任链,除了增加别人的阅读障碍,没有任何明显提升。代码块抽成函数调用,好好取函数名即可。
    我就旗帜鲜明的喜欢 if else
    no1xsyzy
        31
    no1xsyzy  
       2021-04-02 15:51:22 +08:00
    JetBrains MPS ?

    我看到了什么?
    > return True if self.v_value < self.self.start_raise else False
    LeeReamond
        32
    LeeReamond  
       2021-04-02 16:41:19 +08:00 via Android
    @matrix67 他是 python,所以实际不是表驱动,更像是 mapdriven,哪个快不好说,大概率更慢
    matrix67
        33
    matrix67  
       2021-04-03 15:18:05 +08:00
    @LeeReamond #32 这种逻辑一般不会是瓶颈吧。。。
    LeeReamond
        34
    LeeReamond  
       2021-04-03 17:43:14 +08:00
    @matrix67 因为 python 本身慢,再加上没有 switchcase,这种逻辑比原生可能慢个几百倍。有重复运算的部分很容易瓶颈,确实需要找优化方案
    tisswb
        35
    tisswb  
       2021-04-08 16:11:41 +08:00
    @LeeReamond 他来了他来了 他跟着 python3.10 走来了,match case 了解一下
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2972 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 14:38 · PVG 22:38 · LAX 06:38 · JFK 09:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.