[파이썬 디자인 모델] 제2장 백화점 수납 소프트웨어-전략 모델

7763 단어
github 주소:https://github.com/cheesezh/python_design_patterns
제목.
컨트롤러 프로그램을 설계하여 백화점 수납 소프트웨어를 모의하고 고객이 구매한 상품의 단가와 수량에 따라 총 가격을 계산한다.
기본 버전
price = float(input("      :"))
number = int(input("      :"))
total = (price * number)
print("    : %.2f" % total)
      :40
      :9
    : 360.00

평론하다
상술한 절차는 기본적인 기능만 실현했지만 백화점에서 할인 행사가 있는데 예를 들어 20% 할인, 50% 할인 등이 있으면 수요를 만족시키지 못한다. 할인의 방법은 만감 행사가 있을 수 있다. 예를 들어 만300에서 100을 줄이고 만500에서 200을 줄이는 등이다.만약에 할인과 만감 두 가지 판촉 활동만 있다고 가정하면 이것은 마치 지난 장의 계산기와 같이 정상적인 요금, 할인 활동과 만감 활동의 세 가지 계산 방법을 지원하고 간단한 공장 방법으로 실현할 수 있다.
개선 버전 1.0-단순 공장 모드
from abc import ABCMeta, abstractmethod

class CashBase():
    """
       
    """
    __metaclass__ = ABCMeta
    
    def __init__(self):
        self.final_price = None
        
    @abstractmethod
    def accept_cash(self):
        pass

class CashNormal(CashBase):
    """
        
    """
    
    def accept_cash(self, money):
        self.final_price = money
        return self.final_price

class CashRebate(CashBase):
    """
        
    """
    def __init__(self, rebate):
        self.rebate = rebate
    
    def accept_cash(self, money):
        self.final_price = money * self.rebate
        return self.final_price

class CashReturn(CashBase):
    """
        
    """
    def __init__(self, return_condition, return_money):
        self.return_condition = return_condition
        self.return_money = return_money
        
    def accept_cash(self, money):
        if money >= self.return_condition:
            self.final_price = money - self.return_money
        else:
            self.final_price = money
        return self.final_price

class CashFactory():
    """
           
    """
    #     ,      ,  `  .   `  
    cash_accepter_map = {
            "    ": CashNormal(),
            " 300 100": CashReturn(300, 100),
            " 8 ": CashRebate(0.8)
        }
    
    @staticmethod
    def createCashAccepter(cash_type):
        if cash_type in CashFactory.cash_accepter_map:
            return CashFactory.cash_accepter_map[cash_type]
        else:
            return None

클라이언트 코드
price = float(input("      :"))
number = int(input("      :"))
cash_type_list = ["    ", " 300 100", " 8 "]
for i in cash_type_list:
    print("{}:{}".format(cash_type_list.index(i)+1, i))
cash_type_index = int(input("      (1~3)"))

total = price * number
cash_accepter = CashFactory.createCashAccepter(cash_type_list[cash_type_index-1])
print("  : %.2f" % total)
total = cash_accepter.accept_cash(total)
print("  : %.2f" % total)
      :10
      :50
1:    
2: 300 100
3: 8 
      (1~3)3
  : 500.00
  : 400.00

평론하다
  • 할인과 만감을 모두 지원한다면 어떻게 해야 합니까?
  • 간단한 공장 모델은 주로 대상의 창설 문제를 해결하고 대상이 자주 변동하는 문제를 해결할 수 없다. 예를 들어 할인과 만감력은 자주 변화하고 매번 변동할 때마다 코드를 바꿀 수 없다.
  • 알고리즘이 자주 바뀌기 때문에 전략 모델을 사용해야 한다.
  • 포장 변화점은 대상을 대상으로 하는 중요한 사고방식이다.

  • 정책 모드
    이 모델은 알고리즘 가족을 정의하여 각각 봉하여 서로 교체할 수 있도록 한다. 이 모델은 알고리즘의 변화를 알고리즘을 사용하는 고객에게 영향을 주지 않는다.
    from abc import ABCMeta, abstractmethod
    
    class CashBase():
        """
            :   
        """
        __metaclass__ = ABCMeta
        
        def __init__(self):
            self.final_price = None
            
        @abstractmethod
        def accept_cash(self):
            pass
    
    class CashNormal(CashBase):
        """
            :    
        """
        
        def accept_cash(self, money):
            self.final_price = money
            return self.final_price
    
    class CashRebate(CashBase):
        """
            :    
        """
        def __init__(self, rebate):
            self.rebate = rebate
        
        def accept_cash(self, money):
            self.final_price = money * self.rebate
            return self.final_price
    
    class CashReturn(CashBase):
        """
            :    
        """
        def __init__(self, return_condition, return_money):
            self.return_condition = return_condition
            self.return_money = return_money
            
        def accept_cash(self, money):
            if money >= self.return_condition:
                self.final_price = money - self.return_money
            else:
                self.final_price = money
            return self.final_price
    
    class CashContext():
        """
              (    ),         ,             
        """
        def __init__(self, cash_strategy):
            self.cash_strategy = cash_strategy
        
        def get_result(slef, money):
            return self.cash_strategy.accept_cash(money)        

    평론하다
    CashContext 클래스에서 우리는 구체적인 전략 클래스를 전송하여 설정해야 한다. 백화점 수납 소프트웨어라는 장면에서 그것이 바로 서로 다른 요금 전략이다. 그러면 어떻게 서로 다른 요금 전략 대상을 생성합니까?전략 모델과 단순 공장을 결합시킬 수 있다.
    class CashContext():
        """
              (    ),         ,             
        """
        #     ,      ,  `  .   `  
        cash_accepter_map = {
                "    ": CashNormal(),
                " 300 100": CashReturn(300, 100),
                " 8 ": CashRebate(0.8)
            }
        def __init__(self, cash_type):
            self.cash_strategy = CashContext.cash_accepter_map[cash_type]
        
        def get_result(self, money):
            return self.cash_strategy.accept_cash(money)   

    클라이언트 코드
    price = float(input("      :"))
    number = int(input("      :"))
    cash_type_list = ["    ", " 300 100", " 8 "]
    for i in cash_type_list:
        print("{}:{}".format(cash_type_list.index(i)+1, i))
    cash_type_index = int(input("      (1~3)"))
    
    total = price * number
    cash_context = CashContext(cash_type_list[cash_type_index-1])
    print("  : %.2f" % total)
    total = cash_context.get_result(total)
    print("  : %.2f" % total)
          :10
          :10
    1:    
    2: 300 100
    3: 8 
          (1~3)3
      : 100.00
      : 80.00

    평론하다
    전략 모드+단순 공장과 단순 공장 모드의 차이는 어디에 있습니까?
        
    cash_accepter = CashFactory.createCashAccepter(cash_type_list[cash_type_index-1])
    ...
    total = cash_accepter.accept_cash(total)
    
        +    
    cash_context = CashContext(cash_type_list[cash_type_index-1])
    ...
    total = cash_context.get_result(total)
  • 단순 공장에서는 클라이언트가 두 가지 클래스를 인식해야 합니다CashFactoryCashBase
  • .
  • 정책 모델 + 단순 공장, 클라이언트는 하나의 클래스만 알면 된다CashContext
  • 클라이언트가 실례화한 것은 CashContext의 대상이고 CashContextget_result 방법을 호출했기 때문에 구체적인 비용 전략은 클라이언트와 철저하게 분리되고 심지어 전략의 기본 유형CashBase도 클라이언트가 인식할 필요가 없다.

  • 정책 모드 해석
  • 전략 모델은 일련의 알고리즘을 정의하는 방법이다. 개념적으로 보면 모든 이 알고리즘들이 똑같은 작업을 완성했지만 서로 다르다. 똑같은 방식으로 기존의 알고리즘을 호출할 수 있고 각종 알고리즘 클래스와 사용 알고리즘 클래스 간의 결합을 줄일 수 있다[DPE].
  • 정책 모드의 Strategy 단계는 Context에 대해 일련의 재사용 가능한 알고리즘이나 행위를 정의했다.계승은 이러한 알고리즘의 공공 기능 [DP]를 추출하는데 도움이 된다. 예를 들어 계산 비용의 결과 getresult.
  • 정책 모델은 단원 테스트를 간소화할 수 있다. 모든 알고리즘은 자신의 클래스가 있기 때문에 자신의 인터페이스로 [DPE]를 단독으로 테스트할 수 있다.
  • 정책 모델은 알고리즘을 봉인하는 데 사용되지만 실천에서 거의 모든 유형의 규칙을 봉인할 수 있다. 시간에 따라 서로 다른 업무 규칙을 적용하면 정책 모델로 이러한 변화를 처리할 가능성을 고려할 수 있다[DPE].

  • 옥에 티.
    CashContext에서 하나의 dict()형 유형의 변수cash_accepter_map를 사용하여 각종 알고리즘 전략을 저장하고 새로 추가 200 50된 전략을 업데이트cash_accepter_map해야 한다. 이것은 우아해 보이지 않는다. 더욱 우아하고 변경 원가를 낮추기 위해 사용할 수 있다 . 이 기술은 에 소개될 것이다.

    좋은 웹페이지 즐겨찾기