2011-06-17 9 views
2

私はTwistedウェブフレームワークに非常に興味があります。私が知る限り、フレームワーク はハリウッドの原則を使用しています。私はちょうどその言葉を知っているが、このデザインパターンについて全く考えていないのは なのです。 私は、 ハリウッド原則の実装についてPythonでたくさんのGoogle検索を行ってきました。しかし、結果はほとんどありませんでした。 誰も私にこのデザインパターンを説明する簡単なPythonコードを表示できますか?誰かが "ハリウッドの原理" /コントロールの反転を説明するための単純なpythonを与えることができました

+2

これはPythonに固有のものではありません:http://en.wikipedia.org/wiki/Hollywood_Principle –

+3

「ハリウッド原則」という名前があまりにも嫌いです。ファーストクラスの関数*を持つ言語では 'callback'や*完全に普通の何かを呼び出してください。 –

答えて

6

私は実際に "ハリウッド原則"という言葉を聞いたことがありません。また、私はTwistedに精通していません。しかし、制御の逆転という概念はあまり難しくありません。私は、GUIプログラミングはそれを紹介する良い方法だと思います。 here(わずかに変更されています)から以下を考えてください。

import Tkinter 

class App(object): 
    def __init__(self, master): 
     frame = Tkinter.Frame(master) 
     frame.pack() 

     self.button = Tkinter.Button(frame, text="QUIT", fg="red", command=frame.quit) 
     self.button.pack(side=Tkinter.LEFT) 

     self.hi_there = Tkinter.Button(frame, text="Hello", command=self.say_hi) 
     self.hi_there.pack(side=Tkinter.LEFT) 

    def say_hi(self): 
     print "hi there, everyone!" 

root = Tkinter.Tk() 
app = App(root) 

root.mainloop() 

これは制御の逆転の非常に簡単な例です。それはコールバックを使用します。したがって、Hollywood principleモニカ(リンクのためにSvenに感謝します)。考え方は関数を書くことですが、決して呼び出すことはありません。代わりに、別のプログラムに渡して、そのプログラムにいつ呼び出すかを伝えます。次に、そのプログラムを制御します。ここでは、コードの詳細な説明は次のとおりです。

import Tkinter 

class App(object): 

私たちはコールバックを保持し、私は電話するよ何の適切な部分にそれらを渡すクラス定義、で始まる「マスタープログラム」を

​​

クラスには「マスタープログラム」が必要です。マスタープログラムは私たちが定義した関数を呼び出すものです。この場合、GUIのルートウィンドウです。より適切には、GUIプログラミングの文脈において、masterframeであると言うことがあります。

 frame = Tkinter.Frame(master) 
     frame.pack() 

これらの2行は、本質的にウィジェットを含むボックスであるFrameオブジェクトを作成します。あなたはウィジェットが何秒間にあるかを見るでしょう。ご覧のとおり、親もあります - Appmasterと同じものです。

 self.button = Tkinter.Button(frame, text="QUIT", command=frame.quit) 
     self.button.pack(side=Tkinter.LEFT) 

self.buttonはウィジェットです。 Tkinter.Buttonで作成するときは、ラベル(text="QUIT")のようないくつかのプロパティを指定します。あなたはまた、その親が何であるかを伝えます - この場合、masterではなく、frameです。だから我々は階層を持っています - master -> frame -> button。しかし、私たちが最も重要なことは、command=frame.quitです。これは、マウスクリックによってアクティブ化されたときに何をすべきかをボタンに伝えます。要するに、これはコールバックです。ここでは、framequitメソッドを渡します。この場合、プログラム全体が終了します。この関数には()が付いていないことに注意してください。つまり、としたいからです。 buttonに渡したいだけです。

 self.hi_there = Tkinter.Button(frame, text="Hello", command=self.say_hi) 
     self.hi_there.pack(side=Tkinter.LEFT) 

これは最初、唯一の例外ではなく、コールバックとしてself.quitを渡すので、私たちはself.say_hiを通過したことであることにほぼ同じである別のウィジェットです。これは以下で定義されているので、あなたがここで望む関数に置き換えることができます。(ラインの上記セットの両方で、self.button.packはちょうどそれがframeに行くべきButton伝えます。)あなたはHelloボタンが何を定義する場所

def say_hi(self): 
     print "hi there, everyone!" 

say_hiです。

root = Tkinter.Tk() 
app = App(root) 

ここで、インスタンスを作成してクラスを呼び出します。ルートウィンドウを作成し、rootを親としてAppインスタンスを作成します。

root.mainloop() 

これで完了です。残りの作業はTkinterに渡します。

+1

私は、「ハリウッド原理」という言葉は、「私たちに電話しないで、私たちはあなたに電話します」という言葉から来ていると信じています。 – hammar

+0

@ハマー、元の質問に関するSvenのコメントは私のためにその部分を説明しました。なぜ私は以前にそのフレーズに遭遇したことがないのか分かりません... – senderle

2

ツイストは、非同期的なアプローチを用いて設計されています。あなたのプログラムは何かを起こさせますが、そのことが起こるのを待つのではなく、ツイストイベントループ(ねじれた言い回しで「リアクター」)に制御を戻します。原子炉があなたの注意を必要とすることが分かったら、最初にアクションを呼び出すときに指定した 'コールバック'を使ってプログラムを起動します。基本的なワークフローは次のようになります。まず、

something_deferred = make.twisted.do.something() 

something_deferredは通常something()の結果を表すtwisted.internet.defer.Deferredインスタンスです。通常、something()には完了するまでに時間がかかります。したがって、即時にsomething()が返されても、遅延オブジェクトにはまだ結果がありません。あなたがしなければならないことは、結果が実際に準備ができたら、ねじれて呼び出すことができる関数を定義することです。

def something_callback(result): 
    do_something_else(result) 

ほとんどの場合、あなたはまた最後に、あなたはそれがこれらの機能を使用することを捻っ伝える必要があり、

def something_errback(fault): 
    cleanup_something() 

をエラーがsomething()で発生したケースを処理する関数を定義する必要がありますsomething()が最終的に準備ができたら。

something_deferred.addCallbacks(something_callback, something_errback) 

メモ機能を自分で呼び出すことはありませんことを、あなただけのaddCallbacks()に自分の名前を渡します。 Twisted自体があなたの関数を呼び出す責任があります。

すべての例では、この正確なパターンに従いますが、ほとんどの場合、あなたはねじれ定義されたインタフェースを実装するクラスにインスタンスメソッドを置く、またはイベントを生成ツイスト機能に呼び出し可能に合格していません。ハリウッド映画業界では、神経初めての俳優が、時には彼らは一部を得たかどうかを確認するために、オーディションの後に何度も何度もスタジオを呼び出し、ため

2

「ハリウッドの原理は、」そのように命名されます。ソフトウェア開発では、これはpollingと呼ばれ、超効率的です。ハリウッドのメタファーでは、選択される前に繰り返し呼び出されることがあるため、成功した応募者の時間さえも無駄になり、スタジオの時間が無駄になります(選択されなかった多くのアプリケーションがそれに呼ぶためです)。ここで

がうまくいけば、行動原理を照らすPythonのファイルです:

まず、私たちはオーディションのために実行できるActorを、持っている、または一部を取得する:

class Actor(object): 
    def __init__(self, name): 
     self.name = name 

    def youGotThePart(self): 
     print self.name, "got the part." 

    def perform(self): 
     print self.name, "performs an audition." 

その後、我々は持っています鋳造工程:

applicants = [] 
def audition(actor): 
    actor.perform() 
    applicants.append(actor) 

def cast(): 
    import random 
    selection = random.choice(applicants) 
    selection.youGotThePart() 

オーディションを実行するために俳優を要求し、鋳造が発生したときに、俳優をランダムに(選択されている - 非参加者としてハリウッドのプロセスでは、これはおそらく最も現実的なシミュレーションだと思われます)。その俳優はその後通知を受けます(スタジオは「呼び出し」します)。

そして最後に、ここでは全体の鋳造プロセスです:

alice = Actor("alice") 
bob = Actor("bob") 
carol = Actor("carol") 
dave = Actor("dave") 

audition(alice) 
audition(bob) 
audition(carol) 
audition(dave) 

cast() 

あなたが見ることができるように、これは非常に単純であるとGUIやネットワークまたは入力のいずれかの他の外部ソースを必要としません。これは、同じ状態の無駄なチェックと再チェックを避けるためにコードを構造化する単なる方法です。あなたがないにこのプログラムを構造化について考える問題の原則に従っている場合、あなたはこのようなループに何かあるんだけど:誰がどのように何回の俳優を知っているので、

while True: 
    for actor in alice, bob, carol, dave: 
     if actor.didIGetThePart(): 
      break 
    maybeGiveSomeoneThePart() 

もちろん非常に無駄であるかもしれませんスタジオが選ぶ前に電話をかける?

関連する問題