You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Deal类业务逻辑中的IF嵌套地狱问题?

重构Deal状态处理代码:摆脱IF嵌套地狱

首先,你的核心问题是把状态判断、趋势/交叉条件、业务操作三者耦合在了嵌套的IF里,导致代码可读性差、新增规则成本高。下面我会结合你提到的Strategy和责任链模式,再补充一个更易上手的规则表方案,帮你彻底重构这段代码。

问题回顾

你有一个Deal类,包含New、Bought、Finished状态,以及动态变化的trend和crossing属性,需要根据不同场景(开仓、加仓、止盈)的条件匹配执行对应操作。现有代码陷入了IF嵌套地狱:

async def check_deal(deal):
    if deal.is_new():
        if deal.current_trend == UP_TREND and CROSSED_TOP_GREEN in deal.crossing:
            return await deal.create_order(CROSSED_TOP_GREEN)
        if deal.current_trend == FLAT_TREND and CROSSED_BOTTOM_ORANGE in deal.crossing:
            return await deal.create_order(CROSSED_BOTTOM_ORANGE)
        if deal.current_trend == DOWN_TREND and CROSSED_BOTTOM in deal.crossing:
            return await deal.create_order(CROSSED_BOTTOM)
    if deal.is_bought() and not deal.candle_has_order:
        if deal.current_trend == UP_TREND and CROSSED_BOTTOM_GREEN in deal.crossing:
            return await deal.create_order(CROSSED_BOTTOM_GREEN)
        else:
            return await deal.update_deal()
        if deal.current_trend == DOWN_TREND and CROSSED_BOTTOM in deal.crossing:
            return await deal.create_order(CROSSED_BOTTOM)
        else:
            return await deal.update_deal()
    else:
        return await deal.update_deal()
    if deal.is_profitable() and len(deal.orders) == 1 :
        if deal.current_trend == UP_TREND and CROSSED_TOP in deal.crossing:
            return await deal.trailing_enable(CROSSED_TOP)
        if deal.current_trend == FLAT_TREND and CROSSED_TOP_GREEN in deal.crossing:
            return await deal.trailing_enable(CROSSED_TOP_GREEN)
        if deal.current_trend == DOWN_TREND and CROSSED_BASIS in deal.crossing:
            return await deal.trailing_enable(CROSSED_BASIS)
    if deal.is_profitable() and len(deal.orders) > 1:
        if deal.current_trend == UP_TREND and CROSSED_BASIS in deal.crossing:
            return await deal.trailing_enable(CROSSED_BASIS)
        if deal.current_trend == DOWN_TREND and CROSSED_BOTTOM_GREEN in deal.crossing:
            return await deal.trailing_enable(CROSSED_BOTTOM_GREEN)

核心规则

  • current_crossing和current_trend为动态变量
  • 开仓:Deal.is_new() + 趋势&交叉匹配
  • 加仓:Deal.is_bought()且无订单 + 趋势&交叉匹配
  • 止盈:Deal盈利 + 订单数量符合 + 趋势&交叉匹配
  • 加仓场景未匹配规则时,执行update_deal()

重构方案

方案1:规则表驱动(最易实现,推荐新手)

把所有规则抽象成条件-映射-动作的三元组,遍历规则表找到第一个匹配项执行,彻底消除嵌套IF。这种方式代码量少,新增规则只需要加条目,无需修改核心逻辑。

# 先定义场景判断函数,把状态/数量等条件封装成独立函数
def is_open_scenario(deal):
    return deal.is_new()

def is_add_position_scenario(deal):
    return deal.is_bought() and not deal.candle_has_order

def is_take_profit_single(deal):
    return deal.is_profitable() and len(deal.orders) == 1

def is_take_profit_multi(deal):
    return deal.is_profitable() and len(deal.orders) > 1

# 规则列表:每个条目是(场景判断, 趋势-交叉映射, 执行动作)
DEAL_RULES = [
    # 开仓规则
    (
        is_open_scenario,
        {
            (UP_TREND, CROSSED_TOP_GREEN): "create_order",
            (FLAT_TREND, CROSSED_BOTTOM_ORANGE): "create_order",
            (DOWN_TREND, CROSSED_BOTTOM): "create_order",
        },
    ),
    # 加仓规则
    (
        is_add_position_scenario,
        {
            (UP_TREND, CROSSED_BOTTOM_GREEN): "create_order",
            (DOWN_TREND, CROSSED_BOTTOM): "create_order",
        },
    ),
    # 止盈(单订单)
    (
        is_take_profit_single,
        {
            (UP_TREND, CROSSED_TOP): "trailing_enable",
            (FLAT_TREND, CROSSED_TOP_GREEN): "trailing_enable",
            (DOWN_TREND, CROSSED_BASIS): "trailing_enable",
        },
    ),
    # 止盈(多订单)
    (
        is_take_profit_multi,
        {
            (UP_TREND, CROSSED_BASIS): "trailing_enable",
            (DOWN_TREND, CROSSED_BOTTOM_GREEN): "trailing_enable",
        },
    ),
]

async def check_deal(deal):
    # 先处理加仓场景的特殊情况:未匹配规则直接执行update_deal
    if is_add_position_scenario(deal):
        matched = False
        for condition, trend_cross_map in DEAL_RULES:
            if condition(deal):
                trigger = next((c for c in deal.crossing if (deal.current_trend, c) in trend_cross_map), None)
                if trigger:
                    matched = True
                    action = getattr(deal, trend_cross_map[(deal.current_trend, trigger)])
                    return await action(trigger)
        if not matched:
            return await deal.update_deal()
    
    # 遍历所有规则找匹配项
    for condition, trend_cross_map in DEAL_RULES:
        if condition(deal):
            # 找到当前crossing中符合规则的触发项
            trigger = next((c for c in deal.crossing if (deal.current_trend, c) in trend_cross_map), None)
            if trigger:
                action = getattr(deal, trend_cross_map[(deal.current_trend, trigger)])
                return await action(trigger)
    
    # 默认执行update_deal
    return await deal.update_deal()

方案2:Strategy模式(面向对象风格)

把每个场景的处理逻辑封装成独立的策略类,根据Deal的状态选择对应策略执行。这种方式更符合OOP思想,便于单元测试和后续扩展新状态。

from abc import ABC, abstractmethod

class DealStrategy(ABC):
    """策略基类"""
    @abstractmethod
    async def execute(self, deal):
        # 返回None表示该策略不处理,交给下一个策略
        pass

class NewDealStrategy(DealStrategy):
    """开仓场景策略"""
    async def execute(self, deal):
        if not deal.is_new():
            return None
        
        trend_cross_map = {
            (UP_TREND, CROSSED_TOP_GREEN): deal.create_order,
            (FLAT_TREND, CROSSED_BOTTOM_ORANGE): deal.create_order,
            (DOWN_TREND, CROSSED_BOTTOM): deal.create_order,
        }
        trigger = next((c for c in deal.crossing if (deal.current_trend, c) in trend_cross_map), None)
        if trigger:
            return await deal.create_order(trigger)
        return None

class BoughtDealStrategy(DealStrategy):
    """加仓场景策略"""
    async def execute(self, deal):
        if not (deal.is_bought() and not deal.candle_has_order):
            return None
        
        trend_cross_map = {
            (UP_TREND, CROSSED_BOTTOM_GREEN): deal.create_order,
            (DOWN_TREND, CROSSED_BOTTOM): deal.create_order,
        }
        trigger = next((c for c in deal.crossing if (deal.current_trend, c) in trend_cross_map), None)
        if trigger:
            return await deal.create_order(trigger)
        # 加仓场景未匹配规则,直接执行update_deal
        return await deal.update_deal()

class ProfitableSingleStrategy(DealStrategy):
    """止盈(单订单)策略"""
    async def execute(self, deal):
        if not (deal.is_profitable() and len(deal.orders) == 1):
            return None
        
        trend_cross_map = {
            (UP_TREND, CROSSED_TOP): deal.trailing_enable,
            (FLAT_TREND, CROSSED_TOP_GREEN): deal.trailing_enable,
            (DOWN_TREND, CROSSED_BASIS): deal.trailing_enable,
        }
        trigger = next((c for c in deal.crossing if (deal.current_trend, c) in trend_cross_map), None)
        if trigger:
            return await deal.trailing_enable(trigger)
        return None

class ProfitableMultiStrategy(DealStrategy):
    """止盈(多订单)策略"""
    async def execute(self, deal):
        if not (deal.is_profitable() and len(deal.orders) > 1):
            return None
        
        trend_cross_map = {
            (UP_TREND, CROSSED_BASIS): deal.trailing_enable,
            (DOWN_TREND, CROSSED_BOTTOM_GREEN): deal.trailing_enable,
        }
        trigger = next((c for c in deal.crossing if (deal.current_trend, c) in trend_cross_map), None)
        if trigger:
            return await deal.trailing_enable(trigger)
        return None

async def check_deal(deal):
    # 按优先级执行策略,第一个处理的策略返回结果
    strategies = [
        NewDealStrategy(),
        BoughtDealStrategy(),
        ProfitableSingleStrategy(),
        ProfitableMultiStrategy()
    ]
    for strategy in strategies:
        result = await strategy.execute(deal)
        if result is not None:
            return result
    # 默认执行update_deal
    return await deal.update_deal()

方案3:责任链模式(规则优先级明确时使用)

把每个规则处理逻辑封装成链中的节点,Deal对象依次经过每个节点,直到某个节点处理该请求。这种方式适合规则有明确优先级,且后续需要动态调整规则顺序的场景。

from abc import ABC, abstractmethod

class Handler(ABC):
    """责任链节点基类"""
    def __init__(self, next_handler=None):
        self.next_handler = next_handler
    
    @abstractmethod
    async def handle(self, deal):
        pass

class NewDealHandler(Handler):
    """开仓节点"""
    async def handle(self, deal):
        if deal.is_new():
            trend_cross_map = {
                (UP_TREND, CROSSED_TOP_GREEN): deal.create_order,
                (FLAT_TREND, CROSSED_BOTTOM_ORANGE): deal.create_order,
                (DOWN_TREND, CROSSED_BOTTOM): deal.create_order,
            }
            trigger = next((c for c in deal.crossing if (deal.current_trend, c) in trend_cross_map), None)
            if trigger:
                return await deal.create_order(trigger)
        # 不处理则传递给下一个节点
        if self.next_handler:
            return await self.next_handler.handle(deal)
        return await deal.update_deal()

class BoughtDealHandler(Handler):
    """加仓节点"""
    async def handle(self, deal):
        if deal.is_bought() and not deal.candle_has_order:
            trend_cross_map = {
                (UP_TREND, CROSSED_BOTTOM_GREEN): deal.create_order,
                (DOWN_TREND, CROSSED_BOTTOM): deal.create_order,
            }
            trigger = next((c for c in deal.crossing if (deal.current_trend, c) in trend_cross_map), None)
            if trigger:
                return await deal.create_order(trigger)
            # 未匹配规则直接执行update_deal,不再传递
            return await deal.update_deal()
        if self.next_handler:
            return await self.next_handler.handle(deal)
        return await deal.update_deal()

class ProfitableSingleHandler(Handler):
    """止盈(单订单)节点"""
    async def handle(self, deal):
        if deal.is_profitable() and len(deal.orders) == 1:
            trend_cross_map = {
                (UP_TREND, CROSSED_TOP): deal.trailing_enable,
                (FLAT_TREND, CROSSED_TOP_GREEN): deal.trailing_enable,
                (DOWN_TREND, CROSSED_BASIS): deal.trailing_enable,
            }
            trigger = next((c for c in deal.crossing if (deal.current_trend, c) in trend_cross_map), None)
            if trigger:
                return await deal.trailing_enable(trigger)
        if self.next_handler:
            return await self.next_handler.handle(deal)
        return await deal.update_deal()

class ProfitableMultiHandler(Handler):
    """止盈(多订单)节点"""
    async def handle(self, deal):
        if deal.is_profitable() and len(deal.orders) > 1:
            trend_cross_map = {
                (UP_TREND, CROSSED_BASIS): deal.trailing_enable,
                (DOWN_TREND, CROSSED_BOTTOM_GREEN): deal.trailing_enable,
            }
            trigger = next((c for c in deal.crossing if (deal.current_trend, c) in trend_cross_map), None)
            if trigger:
                return await deal.trailing_enable(trigger)
        if self.next_handler:
            return await self.next_handler.handle(deal)
        return await deal.update_deal()

async def check_deal(deal):
    # 构建责任链:注意顺序就是优先级
    handler_chain = ProfitableMultiHandler(
        ProfitableSingleHandler(
            BoughtDealHandler(
                NewDealHandler()
            )
        )
    )
    return await handler_chain.handle(deal)

方案选择建议

  • 规则表驱动:适合快速重构,代码简洁,新增规则只需加条目,学习成本低,推荐新手使用。
  • Strategy模式:适合OOP风格的项目,每个场景逻辑独立,便于单元测试和扩展新状态。
  • 责任链模式:适合规则有明确优先级,且后续需要动态调整规则顺序或新增规则节点的场景。

内容的提问来源于stack exchange,提问作者AlexCrow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:18:30