从基类

时间:2018-01-08 11:15:19

标签: oop inheritance design-patterns

我有一个基类BaseClass,其中包含多个子类SubClass1SubClass2。在实践中,该程序仅适用于其中一个子类的实例。子类使用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

2 个答案:

答案 0 :(得分:1)

为什么不创建一个单独的工厂类,以确保根据子类类型实现正确的保存实现?

答案 1 :(得分:1)

首先:从父级到子级进行依赖是一种糟糕的设计。继承(来自父项的子)是一种依赖。如果从父对象添加另一个依赖关系,则会产生循环依赖关系,并且维护和扩展非常困难。

在面向对象设计启发式中,我们有:

  

启发式5.1:派生类必须根据定义了解其基类,   但基类不应该知道它们的派生类。

<强>为什么吗

  

如果基类知道它们的派生类,那么它就是   暗示如果将新的派生类添加到基类中,则代码   基类的类需要修改。这是不可取的   在基数和派生中捕获的抽象之间的依赖关系   类。我们将看到这些类型的更好的解决方案   我们稍后讨论多态性的主题时的依赖关系   章节。 see reference

因此,将Load()放入父级是不好的设计。

其次:你说:

  

加载已保存的元素时,您不知道要加载的类。

因此,您的客户端仅依赖Save()方法。因此,它们不是您的客户和父母之间的依赖关系。您的客户仅依赖myIntrface

最后:您的客户应该从myInterface定义一个属性。然后,您只需要另一个将对象注入客户端属性的类。 (比如工厂类-as @ VishalRaja的答案 - 或依赖注入者类)。然后,您可以在其中放置所有所需的配置,以决定应传递哪些类实例。