Facade を Ruby で
Facade は、 構造に関するデザインパターンの一つで、 複雑なクラスのシステム、 ライブラリー、 またはフレームワークに対して単純な (しかし限定された) インターフェースを提供します。
Facade は、 アプリケーションの全体としての複雑さを軽減しますが、 それと同時に望ましくない依存性を一箇所に集めるのにも役立ちます。
複雑度:
人気度:
使用例: Facade パターンは、 Ruby のアプリでよく見かけます。 複雑なライブラリーや API を相手にする時、 特に役に立ちます。
見つけ方: 単純なインターフェースのクラスがほとんどの作業を他のクラスに委任していたら、 Facade パターンの使用が識別できます。 通常、 ファサードは、 それが使うオブジェクトのライフサイクルを完全に管理します。
概念的な例
この例は、 Facade デザインパターンの構造を説明するためのものです。 以下の質問に答えることを目的としています:
- どういうクラスからできているか?
- それぞれのクラスの役割は?
- パターンの要素同士はどう関係しているのか?
main.rb: 概念的な例
# The Facade class provides a simple interface to the complex logic of one or # several subsystems. The Facade delegates the client requests to the # appropriate objects within the subsystem. The Facade is also responsible for # managing their lifecycle. All of this shields the client from the undesired # complexity of the subsystem. class Facade # Depending on your application's needs, you can provide the Facade with # existing subsystem objects or force the Facade to create them on its own. def initialize(subsystem1, subsystem2) @subsystem1 = subsystem1 || Subsystem1.new @subsystem2 = subsystem2 || Subsystem2.new end # The Facade's methods are convenient shortcuts to the sophisticated # functionality of the subsystems. However, clients get only to a fraction of # a subsystem's capabilities. def operation results = [] results.append('Facade initializes subsystems:') results.append(@subsystem1.operation1) results.append(@subsystem2.operation1) results.append('Facade orders subsystems to perform the action:') results.append(@subsystem1.operation_n) results.append(@subsystem2.operation_z) results.join("\n") end end # The Subsystem can accept requests either from the facade or client directly. # In any case, to the Subsystem, the Facade is yet another client, and it's not # a part of the Subsystem. class Subsystem1 # @return [String] def operation1 'Subsystem1: Ready!' end # ... # @return [String] def operation_n 'Subsystem1: Go!' end end # Some facades can work with multiple subsystems at the same time. class Subsystem2 # @return [String] def operation1 'Subsystem2: Get ready!' end # ... # @return [String] def operation_z 'Subsystem2: Fire!' end end # The client code works with complex subsystems through a simple interface # provided by the Facade. When a facade manages the lifecycle of the subsystem, # the client might not even know about the existence of the subsystem. This # approach lets you keep the complexity under control. def client_code(facade) print facade.operation end # The client code may have some of the subsystem's objects already created. In # this case, it might be worthwhile to initialize the Facade with these objects # instead of letting the Facade create new instances. subsystem1 = Subsystem1.new subsystem2 = Subsystem2.new facade = Facade.new(subsystem1, subsystem2) client_code(facade) output.txt: 実行結果
Facade initializes subsystems: Subsystem1: Ready! Subsystem2: Get ready! Facade orders subsystems to perform the action: Subsystem1: Go! Subsystem2: Fire!