【问题标题】:Appropriate place for factory class specific generic functions (abstract class?)工厂类特定泛型函数(抽象类?)的适当位置
【发布时间】:2015-10-28 10:25:01
【问题描述】:

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

【问题讨论】:

  • 你可以在抽象类中有具体的实现,这没有错。
  • 也感谢您的保证。感谢您的反馈
  • DBHandler 类看起来很奇怪,因为它不是真正的类,而只是函数的多余容器。这就是模块的意义所在。

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


【解决方案1】:

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

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

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

你可以考虑什么

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

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

【讨论】:

  • 很好的答案。谢谢!
  • @BurningKrome yw;这是你的一个很好的问题。管理方面继承或聚合的位置、内容和方式具有特殊的普遍性和重要性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多