[英]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)
有沒有我可以研究的設計模式可以幫助我解決這個問題?
我最初的想法是創建像Add
、 RemoveByIndex
和RemoveByName
這樣實現__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.