0

我还没有在 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...

处理程序.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...
4

1 回答 1

1

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

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

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

但是你可以考虑什么

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

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

于 2015-10-28T11:27:19.580 回答