python类层次结构的问题

Ale*_*der 4 python oop

我有一个类层次结构:

class ParentClass:

    def do_something(self):
        pass # child classes have their own implementation of this

class ChildClass1(ParentClass):

    def do_something(self):
        <implementation here>

class ChildClass2(ParentClass):

    def do_something(self, argument_x):
        <implementation here>

class ChildClass3(ParentClass):

    def do_something(self, argument_y):
        <implementation here>
Run Code Online (Sandbox Code Playgroud)

这里有两个问题:

  • 方法do_something()在子类中有不同的接口:它接受子类2和3中的参数,但在子类1中没有参数
  • do_something()的参数具有不同的名称,以强调它们在子类2和3中具有不同的含义.这将从下面的用法示例中变得更加清晰

这是类的使用方式:

有一个返回实例的工厂类:

class ChildFactory:

    def get_child(self, argument):
        if argument == '1':
            return ChildClass1()
        elif argument == '2':
            return ChildClass2()
        elif argument == '3':
            return ChildClass3()
Run Code Online (Sandbox Code Playgroud)

稍后在代码中:

...
# pseudocode, not python
child_type = ? # can have values '1', '2' or '3' at this moment
var1 = 1
var2 = 'xxx'
# var1 and var2 have different types, just to emphasize the difference in their
# meaning when being passed as arguments to do_something()
# this was mentioned above (the second problem)
child = ChildFactory.get_child(child_type)
if child is an instance of ChildClass1, child.do_something() is called
if child is an instance of ChildClass2, child.do_something(var1) is called
if child is an instance of ChildClass3, child.do_something(var2) is called
# end of pseudocode
Run Code Online (Sandbox Code Playgroud)

问题:

  1. 上面提到的两个问题是否是一个糟糕设计的标志?如果是这样,设计层次结构的正确方法是什么?
  2. 如何在python中统一编写伪代码片段?主要关注的是避免对每个特定情况使用巨大的if/else语句,因为它会使来自ChildFactory.get_child()的if/else语句加倍

S.L*_*ott 10

具有相同名称和不同参数的方法是代码气味.

"方法do_something()在子类中有不同的接口:它接受子类2和3中的参数,但在子类1中没有参数"

你不说为什么.有两个很好的理由

  • 子类1具有默认值.

  • 子类2忽略了该值.

几乎任何其他原因都表明它do_something真正不同的,应该有不同的名称.

如果子类1具有默认值,则只需在方法函数的参数中显式编写默认值.

class ChildClass1( ParentClass ):
    def do_something( argument_x= None )
        ....
Run Code Online (Sandbox Code Playgroud)

如果子类1忽略该值,则只需忽略该值.不要站在你的头上忽略一个角.

class ChildClass1( ParentClass ):
    def do_something( argument_x )
        return True
Run Code Online (Sandbox Code Playgroud)

没有使用所有参数值的多态方法函数没有魔力.

"do_something()的参数有不同的名称,以强调它们在子类2和3中有不同的含义."

这只是糟糕的设计.您不能使用具有不同参数名称的相同方法函数,因为它们执行不同的操作.

拥有相同的方法函数名称是错误的.如果它们是类似事物的不同实现,那么参数将具有基本相同的含义.

如果他们实际上做了不同的事情,那么你没有多态性,你不应该给这些方法赋予相同的名称.

当两个类中的方法做了根本不同的事情 - 需要具有不同名称的不同参数以使其显而易见时 - 这些方法必须不具有相同的名称.当名称没有描述该方法实际执行的内容时,该名称就不再具有意义.

注意

你的代码BTW将在Python中运行,因为鸭子打字.只要方法名称匹配,参数类型就不必接近匹配.然而,这是非常糟糕的设计,因为这些方法之间的本质区别是如此巨大.