![Bridge](/images/patterns/cards/bridge-mini.png?id=b389101d8ee8e23ffa1b534c704d0774)
Bridge を C# で
Bridge は、 構造に関するデザインパターンの一つで、 ビジネス・ロジックや巨大なクラスを独立して開発可能なクラス階層に分割します。
階層の一つ (抽象化と呼ばれる) は、 二つ目の階層 (実装) のオブジェクトへの参照を持ちます。 抽象化階層は、 その呼び出しのいくつか (場合によっては大多数) を実装階層のオブジェクトに委任します。 すべての実装は、 共通のインターフェースを持っているので、 抽象化の中で入れ替え可能です。
複雑度:
人気度:
使用例: Bridge パターンは、 クロス・プラットフォーム・アプリを扱う時、 複数の種類のデータベース・サーバーをサポートする時、 あるいはある種の API プロバイダー (クラウド・プラットフォーム、 ソーシャル・ネットワークなど) を複数利用したい場合に特に便利です。
見つけ方: Bridge は、 制御するものと、 それが依存するいくつかの異なるプラットフォームとが明らかに分かれていることから識別できます。
概念的な例
この例は、 Bridge デザインパターンの構造を説明するためのものです。 以下の質問に答えることを目的としています:
- どういうクラスからできているか?
- それぞれのクラスの役割は?
- パターンの要素同士はどう関係しているのか?
Program.cs: 概念的な例
using System;
namespace RefactoringGuru.DesignPatterns.Bridge.Conceptual
{
// The Abstraction defines the interface for the "control" part of the two
// class hierarchies. It maintains a reference to an object of the
// Implementation hierarchy and delegates all of the real work to this
// object.
class Abstraction
{
protected IImplementation _implementation;
public Abstraction(IImplementation implementation)
{
this._implementation = implementation;
}
public virtual string Operation()
{
return "Abstract: Base operation with:\n" +
_implementation.OperationImplementation();
}
}
// You can extend the Abstraction without changing the Implementation
// classes.
class ExtendedAbstraction : Abstraction
{
public ExtendedAbstraction(IImplementation implementation) : base(implementation)
{
}
public override string Operation()
{
return "ExtendedAbstraction: Extended operation with:\n" +
base._implementation.OperationImplementation();
}
}
// The Implementation defines the interface for all implementation classes.
// It doesn't have to match the Abstraction's interface. In fact, the two
// interfaces can be entirely different. Typically the Implementation
// interface provides only primitive operations, while the Abstraction
// defines higher- level operations based on those primitives.
public interface IImplementation
{
string OperationImplementation();
}
// Each Concrete Implementation corresponds to a specific platform and
// implements the Implementation interface using that platform's API.
class ConcreteImplementationA : IImplementation
{
public string OperationImplementation()
{
return "ConcreteImplementationA: The result in platform A.\n";
}
}
class ConcreteImplementationB : IImplementation
{
public string OperationImplementation()
{
return "ConcreteImplementationB: The result in platform B.\n";
}
}
class Client
{
// Except for the initialization phase, where an Abstraction object gets
// linked with a specific Implementation object, the client code should
// only depend on the Abstraction class. This way the client code can
// support any abstraction-implementation combination.
public void ClientCode(Abstraction abstraction)
{
Console.Write(abstraction.Operation());
}
}
class Program
{
static void Main(string[] args)
{
Client client = new Client();
Abstraction abstraction;
// The client code should be able to work with any pre-configured
// abstraction-implementation combination.
abstraction = new Abstraction(new ConcreteImplementationA());
client.ClientCode(abstraction);
Console.WriteLine();
abstraction = new ExtendedAbstraction(new ConcreteImplementationB());
client.ClientCode(abstraction);
}
}
}
Output.txt: 実行結果
Abstract: Base operation with:
ConcreteImplementationA: The result in platform A.
ExtendedAbstraction: Extended operation with:
ConcreteImplementationA: The result in platform B.