我有一个基类BaseClass
,其中包含多个子类SubClass1
,SubClass2
。在实践中,该程序仅适用于其中一个子类的实例。子类使用save
方法实现接口。加载已保存的元素时,您不知道要加载的类。因此我考虑在基类中使用load
方法,但这引发了一个问题:如何从基类中的一个子类实例化一个元素?
For clarity, here is some simple code:
class BaseClass:
def load(self):
#load element of subclass
return subclass_element
class myInterface:
__metaclass__ = ABCMeta
@abstractmethod
def save(self):
raise NotImplementedError
class SubClass1(BaseClass, myInterface):
def save(self):
#save the element
class SubClass2(BaseClass, myInterface):
def save(self):
#save the element
我也对任何支持不同设计的建议持开放态度。我不确定我是不是在实施反模式。
编辑1:添加工厂类
根据我对@Vishal_Raja和@ Gholamali-Irani建议的理解:
class SubClassLoader: #this is our factory class
registered_subclasses = {} #static dict of subclasses
@StaticMethod
def register(classname, class):
SubClassLoader.registered_subclasses[classname] = class
@StaticMethod
def get_instance(filepath):
classname, arguments = get_classname(filepath)
if classname in SubClassLoader.registered_subclasses:
return SubClassLoader.registered_subclasses[classname](arguments)
else:
raise TypeError("Unknown class %s" % classname)
class BaseClass:
pass
class myInterface:
__metaclass__ = ABCMeta
@abstractmethod
def save(self):
raise NotImplementedError
class SubClass1(BaseClass, myInterface):
def save(self):
#save the element
class SubClass2(BaseClass, myInterface):
def save(self):
#save the element
答案 0 :(得分:1)
为什么不创建一个单独的工厂类,以确保根据子类类型实现正确的保存实现?
答案 1 :(得分:1)
首先:从父级到子级进行依赖是一种糟糕的设计。继承(来自父项的子)是一种依赖。如果从父对象添加另一个依赖关系,则会产生循环依赖关系,并且维护和扩展非常困难。
在面向对象设计启发式中,我们有:
启发式5.1:派生类必须根据定义了解其基类, 但基类不应该知道它们的派生类。
<强>为什么吗
如果基类知道它们的派生类,那么它就是 暗示如果将新的派生类添加到基类中,则代码 基类的类需要修改。这是不可取的 在基数和派生中捕获的抽象之间的依赖关系 类。我们将看到这些类型的更好的解决方案 我们稍后讨论多态性的主题时的依赖关系 章节。 see reference
因此,将Load()
放入父级是不好的设计。
其次:你说:
加载已保存的元素时,您不知道要加载的类。
因此,您的客户端仅依赖Save()
方法。因此,它们不是您的客户和父母之间的依赖关系。您的客户仅依赖myIntrface
。
最后:您的客户应该从myInterface
定义一个属性。然后,您只需要另一个将对象注入客户端属性的类。 (比如工厂类-as @ VishalRaja的答案 - 或依赖注入者类)。然后,您可以在其中放置所有所需的配置,以决定应传递哪些类实例。