0

スタック オーバーフローに関するこの特定の質問に対する回答が見つからなかったので、ここに投稿します。

必要なデータベースに応じて、抽象クラスからデータベース処理オブジェクトを生成するファクトリ クラスがあります (コードを参照)。

私の質問はこれです。データベースハンドラーにのみ適用できる一般的なメソッドがいくつかあります...そのため、それらを独自のモジュールに配置するのは適切ではないと思います...しかし、それらを配置する適切な場所がどこにあるかわかりません。

それらを抽象クラスに入れることは確かに機能しますが、それが受け入れられる場所かどうかはわかりません。

抽象クラス

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

1 に答える 1

1

代替案を除外して、その設計上の問題に取り組みましょう。

  • 抽象基本クラスに共通の保護関数を実装しない場合は、具体的な子孫でその実装を繰り返す必要があり、DRY原則に違反します。
  • 共変の handler() ファクトリの製品に_check_host実装mixinスタイルを集約させる場合、具体的な DBHandler_XXXX は独自の ctors 要件を満たさないため、暗黙のうちに抽象化されます。そのため、有効な具体的な製品インスタンスはありますが、有効な製品クラスはありません。これは、ファクトリ パターンを弱体化させて維持することも悪いことではありません。

あなたのデザインがそれらのゆがみより優れていることは明らかです。

ただし、考慮できること

  • それがすべての DBHandler_XXXX の子孫で実行可能な場合 (!) -

抽象基本クラスの ctor を呼び出し_check_hostており、その ctor を適切な時点で DBHandler_XXXX から明示的に呼び出しています。

于 2015-10-28T11:27:19.580 に答える