簡體   English   中英

Python - 重構在不同類中發現的類似方法

[英]Python - Refactor similar methods found in different classes

我想重構幾個具有相同和/或相似方法的類。 類的數量約為 20,類似方法的數量約為 15。 這個空間中存在各種組合,這就是為什么我有點不願意使用繼承來解決這個問題(正確的?)。

該代碼是由 com api 控制的另一個應用程序的包裝器的一部分。 包裝器又是在我工作的公司內部分發的包的一部分。 因此類的接口必須保持不變(為了向后兼容)。

這個例子說明了這些類的一些非常簡化的版本:

class FirstCollectionLike:
    def __init__(self):
        self._collection = list()

    def add(self, arg):
        self._collection.append(arg)

    def remove(self, index):
        del self._collection[index]


class SecondCollectionLike:
    def __init__(self):
        self._collection = list()
        self._resource = some_module.get_resource()

    def start(self):
        some_module.start(self.resource)

    def add(self, arg):
        self._collection.append(arg)

    def remove(self, value):
        self._collection.remove(value)


class SomeOtherClass:
    def __init__(self):
        self._some_attribute = 0
        self._resource = some_module.get_resource()

    def add(self, value):
        self._some_attribute += value

    def start(self):
        some_module.start(self._resource)

有沒有我可以研究的設計模式可以幫助我解決這個問題?

我最初的想法是創建像AddRemoveByIndexRemoveByName這樣實現__call__方法類,如下所示:

class Add:
    def __init__(self, owner):
        self.owner = owner

    def __call__(self, item):
        self._collection.append(item)

class AddAndInstantiate:
    def __init__(self, owner, type_to_instantiate):
        self.owner = owner
        self.type_to_instantiate = type_to_instantiate

    def __call__(self, name):
        self._collection.append(type_to_instantiate(name))

然后將這些類的實例作為實例屬性分配給它們各自的所有者對象:

class RefactoredClassOne:
    def __init__(self):
        self.add = Add(self)
        self.remove = RemoveByIndex(self)

class RefactoredClassTwo:
    def __init__(self):
        self.add = AddAndInstantiate(self, SomeClass)
        self.remove = RemoveByName(self)

通過這種方式,我可以很容易地將任何我想要的方法添加到類中,並在需要時向方法類提供一些參數(如上面示例中要實例化的類的類型)。 缺點是跟蹤正在發生的事情有點困難,如果以這種方式實現方法,我們使用的自動文檔生成 (sphinx) 將不起作用。

這看起來是一個糟糕的方法嗎? 有哪些替代方案?

首先,如果您的類像示例所建議的一樣簡單,我不確定 OOP 是正確的工具。 你的類所做的只是重命名幾個基本調用。 這是無用的抽象和 IMO 不好的做法(為什么強迫我查看SecondClassCollectionLike.py文件以發現.add()是 1)實際上是一個錯誤命名的append和 2)我的集合實際上是一個list好聽的名字?)

在這種情況下,我會說函數式方法可能更好,工作流程例如:

a = SecondClassCollectionLike()
a.add("x")
a.add("y")
a.remove(0)
a.start()

將是一個更加清晰,如果它看起來像

a = list()
a.append("x")
a.append(y)
del a[0]
somemodule.start()

如果您的類實際上更復雜,並且您真的想保留 OOP 方法,我認為此解決方案可能接近您的解決方案以及您正在尋找的內容。

這個想法是擁有包含邏輯的模塊。 例如_collection_behaviour.py模塊,它包含add()remove()increment()或其他任何內容。 還有一個_runtime.py模塊,其中包含start()stop()等邏輯。

通過這種方式,您可以擁有從這些模塊中表現出行為的類:

calss MyClass():
    def __init__(self):
        self._collection = list()

    from ._collection_behaviour import add
    from ._collection_behaviour import remove
    from ._runtime import start

但是我不認為讓這些函數類實現__call__如果這就是他們所做的一切。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM