【问题标题】:Generalize class method that does slightly different actions according to condition泛化根据条件执行略有不同动作的类方法
【发布时间】:2020-05-21 06:49:06
【问题描述】:

我有一个简化的类Animal,它可以做food_routine,其中的动作因动物的类型而异:

DOG = 'dog'
CAT = 'cat'

class Animal(object):
    def __init__(self, animal_type):
        if animal_type not in [CAT, DOG]:
            raise Exception('unexpected animal')
        self.animal_type = animal_type

    def food_routine(self):
        self.come_to_plate()  # common code
        self.sniff_food()  # common code

        if self.animal_type == CAT:
            self.go_around_plate()

        self.eat_the_food()  # common code

        if self.animal_type == DOG:  # condition I want to avoid
            self.thank_owner()

        self.go_away_from_plate()  # common code

        # cats and dogs do different things after eating:
        if self.animal_type == CAT:  # condition I want to avoid
            self.go_lie_on_couch()
        elif self.animal_type == DOG:  # condition I want to avoid
            self.ask_for_walk_outside()

        self.sleep()  # common code

    def sleep(self):
        print 'sleep'  # common code

    def ask_for_walk_outside(self):
        print 'ask for a walk outside'

    def go_lie_on_couch(self):
        print 'go lie on couch'

    def go_away_from_plate(self):
        print 'go away from plate'  # common code

    def thank_owner(self):
        print 'thank owner'  # only dogs thank owner

    def eat_the_food(self):
        print 'eat the food'  # common code

    def go_around_plate(self):
        print 'go around plate'

    def sniff_food(self):
        print 'sniff food'  # common code

    def come_to_plate(self):
        print 'come to plate'  # common code

我的问题是 if 语句使代码不可读。我试图通过创建两个类来解决它:一个用于 Dog,一个用于 Cat。每只动物只做他知道在food_routine 中做的事情(并从Animal 中删除了该方法):

class Cat(Animal):
    def food_routine(self):
        self.come_to_plate()  # common code
        self.sniff_food()  # common code
        self.go_around_plate()
        self.eat_the_food()  # common code
        self.go_away_from_plate()  # common code
        self.go_lie_on_couch()
        self.sleep()  # common code


class Dog(Animal):
    def food_routine(self):
        self.come_to_plate()  # common code
        self.sniff_food()  # common code
        self.eat_the_food()  # common code
        self.thank_owner()
        self.go_away_from_plate()  # common code
        self.ask_for_walk_outside()
        self.sleep()  # common code

这会导致我想要避免的代码重复(common code 行)。

所以我的问题是:什么是避免代码重复和避免if 语句以使代码可读和简单的好习惯?

【问题讨论】:

    标签: python oop polymorphism


    【解决方案1】:

    food_routine 应该是相互的。

    将您的操作分为几个阶段 - “操作前”、“操作”、“操作后”。 每个类都应该实现“pre action”函数和“post action”函数,Animal 类应该包含所有的公共代码。 每只狗/猫都应该调用超级“pre”和“post”以避免代码重复。

    class Animal(object):
        .
        .
        .
        def action():
            self.eat_the_food()  # common code
    
        def pre_action():
            self.come_to_plate()  # common code
            self.sniff_food()  # common code
    
        def post_action():
            self.go_away_from_plate()  # common code
            self.sleep()  # common code
    
    
    class Cat(Animal):
        .
        .
        def pre_action():
            super().pre_action()
            self.go_around_plate()
    
    
    class Dog(Animal)
        .
        .
        .
        def post_action():
            self.thank_owner()
            self.ask_for_walk_outside()
            self.super().post_action()
    

    然后,每个调用可以是:

    Dog.pre_action()
    Dog.action()
    Dog.post_action()
    

    【讨论】:

      【解决方案2】:

      怎么样:

      def food_routine(self):
          self.come_to_plate()  # common code
          self.sniff_food()  # common code
      
          self._pre_eat_action()
      
          self.eat_the_food()  # common code
      
          self._post_eat_action()
      
          self.go_away_from_plate()  # common code
      
          self._post_leave_plate_action()
      
          self.sleep()  # common code
      

      然后在DogCat 中实现_pre_eat_action_post_eat_action_post_leave_plate_action 来处理这两种不同的行为。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-17
        • 2011-11-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多