工厂 class 特定通用函数的适当位置(抽象 class?)

Appropriate place for factory class specific generic functions (abstract class?)

我还没有在 Stack Overflow 上找到这个特定问题的答案,所以我把它贴在这里。

我有一个工厂 class,它根据您需要的数据库(参见代码)从抽象 class 生成数据库处理对象。

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

将它们放在摘要中 class 当然可行,但我不知道那是否是他们接受的地方。

摘要class

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

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

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...

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

  • 如果您不在抽象基类中实现公共保护函数 class 您将不得不在具体后代中重复其实现,这将违反 DRY 原则
  • 如果你想让协变处理程序()工厂的产品聚合 _check_host 实现 mixin 风格,具体 DBHandler_XXXX 不满足他们自己的 ctors 要求,因此隐含地抽象自己。因此会有有效的具体产品实例,但不是有效的产品 classes,这不仅不利于维护,还会淡化工厂模式。

很明显你的设计比那些扭曲的要好。

你可以考虑什么

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

在抽象基础 classes 的构造函数中调用 _check_host,并在适当的点从 DBHandler_XXXX 显式调用该构造函数。