1

私はここでかなりの穴に身を掘りました。

私は PyDev で Python/Kivy アプリに取り組んでいます。

アプリは多くのシステム (約 10) で実行されるため、すべてを処理するためにそれらをエンジンに押し込みました。

簡単にアクセスできるように、(最悪の) シングルトンを介してエンジンを取得します。

main.py

#main.py
from code import engine

class MyApp(App):
    def build(self):
        engine.GetInstance().Initialize()

if __name__ == '__main__':
    MyApp().run()

エンジン.py

#engine.py
from code import system1
from code import system2

gEngineInstance = None
def GetInstance():
    global gEngineInstance
    if (gEngineInstance == None):
        gEngineInstance = Engine()
    return gEngineInstance

class Engine():
    mSystem1 = None
    mSystem2 = None

    def Initialize(self):
        self.mSystem1 = system1.System1()
        self.mSystem2 = system2.System2()
    # Omitted

残念ながら、これにより厄介な循環依存関係が発生しました。

Main はエンジンを作成し、システムのインポートを実行するエンジンのインポートを実行するエンジンについて知る必要があります。問題: システムがインポートしてからエンジンをインポートする、循環参照。

system1.py

#system1.py
from code import engine

class System1():
    def SomeMethod(self):
        engine.GetInstance().mSystem2.DoThings()

あなたは絵を手に入れます。私は今のところ、この恐ろしいコードをいたるところに使用してこれをバイパスしました。

system1.py

#system1.py

class System1():
    def SomeMethod(self):
        from code import engine
        engine.GetInstance().mSystem2.DoThings()

これにより、その行までインポートが停止します。これは問題ありませんが、間違っているように見えます。すべてが間違っているように感じます。

Engine をすべてのシステム コンストラクターへの参照として渡すだけの誘惑に駆られますが、それは少しリファクタリングする必要があり、将来のためにこの種のシングルトン/循環参照の問題を修正するためのより適切な方法があるかどうかを知りたいです。

4

1 に答える 1

2

system各モジュールがモジュールEngineレベルのコードを使用してクラスに「登録」する「登録」メカニズムを使用するのはどうでしょうか。

engine.py

class Engine():
    @classmethod
    def register(cls, type):
        ...

system1.py

from engine import Engine

class System1():
    ...

Engine.register(System1)

そうEngineすれば、何が接続されているかを直接知る必要はありません。

于 2013-03-05T05:29:21.967 に答える