类设计:共享许多相同代码的方法

时间:2012-09-21 12:38:24

标签: python oop methods

我想在这时创建一个有两种方法的类(我也希望能够 明显改变班级)。

class ogrGeo(object):

    def __init__(self):
        pass

    def CreateLine(self, o_file, xy):
        #lots of code


    def CreatePoint(self, o_file, xy):
        # lot's of the same code as CreateLine(), 
        # only minor differences

保持干净并重复 尽可能少的代码我要求一些建议。两种方法CreateLine()CreatePoint()分享了很多代码。减少冗余: 应该定义两种方法都可以调用的第三种方法吗? 在这种情况下你仍然可以打电话     o = ogrGeo() o.CreateLine(...) o.CreatePoint(...) seperatly。 或者我应该将它们合并为一种方法?还有其他解决方案我没想过或者一无所知吗?

非常感谢您的任何建议。

5 个答案:

答案 0 :(得分:3)

是否应将方法合并为一个是API设计的问题。如果功能有不同的目的,那么你将它们分开。如果客户端代码可能遵循模式

,我合并它们
if some_condition:
    o.CreateLine(f, xy)
else:
    o.CreatePoint(f, xy)

但是否则,不要合并。相反,如果公共代码不触及self,则将公共代码重构为私有方法,甚至重构为独立函数。 Python没有内置于该语言中的“私有方法”的概念,但具有前导_的名称将被识别为。

答案 1 :(得分:2)

将公共代码分解为(私有)辅助方法是完全正常的:

class ogrGeo(object)
    def __init__(self):
        pass

    def CreateLine(self, o_file, xy):
        #lots of code
        value = self._utility_method(xy)

    def CreatePoint(self, o_file, xy):
        # lot's of the same code as CreateLine(), 
        # only minor differences
        value = self._utility_method(xy)

    def _utility_method(self, xy):
        # Common code here
        return value

该方法可以返回一个值,也可以直接操作self上的属性。

建议:阅读Python style guide并坚持其惯例。大多数其他python项目都可以,如果你这样做,它将使你的代码更易于理解其他Python开发人员。

答案 2 :(得分:1)

对于将重叠的代码片段,请考虑这些代码片段是否也可以是各自独立的函数。然后CreateLine将包含对某些函数的多次调用,其中参数选择对CreateLine有意义,同时CreatePoint将是几个函数调用,其中包含用于创建点的适当参数。

即使这些新的辅助功能不会在别处使用,最好将它们模块化为单独的功能,而不是复制/粘贴代码。但是,如果创建这些结构所需的辅助功能非常具体,那么为什么不把它们分解成自己的类呢?

你可以制作一个"对象"涉及创建对象的所有基础知识的类,然后使用" Line"和" Point"派生自" Object"的类。在这些类中,覆盖必要的功能,以便构造是特定的,依赖于基础中的辅助功能"对象"重叠代码部分的类。

然后ogrGeo类将构造这些其他类的实例。即使是" Line"的最终消费者或"形状"不需要完整的类对象,您仍然可以使用此设计,并使ogrGeo能够返回消费者希望使用的Line实例或Point实例的子部分。

答案 3 :(得分:1)

这几乎不重要。您希望类方法尽可能地用于调用程序,并且使用两个方法比使用单个方法为要创建的对象类型具有附加参数更简单,更有效:

def CreateObj(self, obj, o_file, xy)    # obj = 0 for Point, 1 for Line, ...

建议:使用单独的API调用并将公共代码分解为可在类中调用的方法。

答案 4 :(得分:0)

你也可以走向另一个方向。特别是如果以下情况:

def methA/B(...):
    lots of common code
    small difference
    lots of common code

然后你可以做

def _common(..., callback):
    lots of common code
    callback()
    lots of common code
def methA(...):
    def _mypart(): do what A does
    _common(..., _mypart)
def methB(...):
    def _mypart(): do what B does
    _common(..., _mypart)