工厂类特定泛型函数的适当位置(抽象类?)

时间:2015-10-28 10:25:02

标签: python inheritance abstract-class factory-pattern generalization

我还没有在Stack Overflow上找到这个具体问题的答案,所以我在这里发帖。

我有一个工厂类,它从抽象类生成数据库处理对象,具体取决于您需要的数据库(请参阅代码)。

我的问题是这个;我有一些通用的方法,它们只适用于数据库处理程序......所以我认为将它们放入自己的模块中是不合适的......但是我不确定放置它们的适当位置。

将它们放在抽象课堂当然有效,但我不知道这是否是他们接受的地方。

抽象类

class DBHandlerAbstract(object): # ABSTRACT CLASS ---

    __metaclass__ = abc.ABCMeta

    # I HAVE TO BE OVERRIDDEN
    @abc.abstractmethod
    def open(self):
        raise NotImplementedError

    # I HAVE TO BE OVERRIDDEN
    @abc.abstractmethod
    def close(self):
        raise NotImplementedError

    # SHOULD THIS GF GO HERE OR ELSEWHERE???
    def _check_host(self):
        print 'this will be the same for all dbhandler objects'

工厂类

class DBHandler(object): # FACTORY CLASS ---
    """
    This is a factory class that will call and return a subclass.

    It is NOT an abstract class.

    The objects classes that are instantiated by this factory will be 
    subclasses of DBHandler  
    """
    @staticmethod
    def handler(service, *args, **kwargs):
        # Microsoft SQL (mssql)
        if      re.match("^(\s*)ms(\s*)sql.*$", str(service.lower())):
            return DBHandler_MSSQL(*args, **kwargs)

        # MySQL
        elif    re.match("^(\s*)my(\s*)sql.*$", str(service.lower())):
            return DBHandler_MYSQL(*args, **kwargs)

        else:
            log.error(MSG.DBHandlerNotProvided())
            raise TypeError('DBHandler service not provided.')

功能类

class DBHandler_MSSQL(DBHandlerAbstract): # FUNCTIONAL CLASS ---
    def __init__(self, *args, **kwargs):

        self.args       = args
        self.kwargs     = kwargs

        self._check_host()

        ...stuff and things...

gethandler.py

class test(object):

    def __init__(self):
        app_name   = 'dbhandler_test'
        logfile    = 'system'
        log_level  = 10
        screendump = True

        DBO = DBHandler.handler('mssql')

        ...stuff and things...

1 个答案:

答案 0 :(得分:1)

让我们通过排除替代方案来解决设计问题:

  • 如果您不在抽象基类中实现公共保护函数,则必须在具体后代中重复其实现,这将违反DRY原则
  • 如果您将covariant handler()工厂的产品聚合_check_host实现mixin - 样式,具体的DBHandler_XXXX不能满足他们自己的ctors要求,因此本身就是隐式抽象的。所以会有有效的产品实例,但不是有效的产品类别,这也不仅仅是维持工厂模式的水质。

很明显,你的设计优于那些扭曲。

你可以考虑什么

  • 如果这对所有DBHandler_XXXX后代(!) -
  • 都可行

在抽象基类的ctor中调用_check_host,并在适当的位置从DBHandler_XXXX中显式调用该ctor。