|
BRIDGE
抽出クラスと実装を分離するパターンです。
このパターンを利用して、実装依存部分を分離すれば、アプリケーション固有の設計抽象度を向上させることができます。
言いかえれば、フレームワークの実装に依存する部分を局所化することによって、アプリケーションの基本設計部分への影響を低減させることができます。
『BRIDGEの骸骨』では、Abstraction クラスのサブクラス定義を省略しています。
■ 『BRIDGEの骸骨』の構造

■ 『BRIDGEの骸骨』 プログラム・コード
| □ Java2版 |
// Copyright(C) 2000-2003 Yoshinori Oota All rights reserved.
import java.awt.*;
public class BridgeSample {
static public void main(String[] args) {
Abstraction abstraction = new Abstraction("A");
abstraction.Operation();
abstraction = new Abstraction("B");
abstraction.Operation();
}
}
class Abstraction {
private Implementor _imp = null;
public Abstraction(String sw) {
if (sw.equals("A")) {
_imp = new ImplementorA();
} else if (sw.equals("B")) {
_imp = new ImplementorB();
}
}
public void Operation() {
_imp.OperationImp();
}
}
abstract class Implementor {
abstract public void OperationImp();
}
class ImplementorA extends Implementor {
public void OperationImp() {
System.out.println("Call ImplementorA::OperationImp()");
}
}
class ImplementorB extends Implementor {
private Frame _frame = new Frame("BridgeSample");
public void OperationImp() {
_frame.add(new Label("Call ImplementorB::OperationImp()", Label.CENTER));
_frame.setSize(250, 100);
_frame.show();
}
}
|
| ○ C++版 |
// Copyright(C) 2003 Yoshinori Oota All rights reserved.
#include <windows.h>
#include <iostream>
using namespace std;
class Implementor {
public:
Implementor();
virtual ~Implementor();
virtual void OperationImp() const = 0;
};
class ImplementorA : public Implementor {
public:
ImplementorA();
virtual ~ImplementorA();
virtual void OperationImp() const;
};
class ImplementorB : public Implementor {
public:
ImplementorB();
virtual ~ImplementorB();
virtual void OperationImp() const;
};
class Abstraction {
public:
Abstraction(char sw);
virtual ~Abstraction();
virtual void Operation() const; // 継承を考慮し仮想関数としておく
protected:
Implementor* imp_;
};
Implementor::Implementor() { }
Implementor::~Implementor() { }
ImplementorA::ImplementorA() { }
ImplementorA::~ImplementorA() { }
void ImplementorA::OperationImp() const {
cout << "Call ImplementorA::OperationImp()" << endl;
}
ImplementorB::ImplementorB() { }
ImplementorB::~ImplementorB() { }
void ImplementorB::OperationImp() const {
MessageBox(0, "Call ImplementorB::OperationImp", "AdapterSample", MB_OK|MB_SETFOREGROUND);
}
Abstraction::Abstraction(char sw) : imp_(NULL) {
if (sw == 'A') {
imp_ = new ImplementorA();
} else if (sw == 'B') {
imp_ = new ImplementorB();
}
}
Abstraction::~Abstraction() {
delete imp_;
}
void Abstraction::Operation() const {
imp_->OperationImp();
}
int main() {
Abstraction* abstraction = new Abstraction('A');
abstraction->Operation();
delete abstraction;
abstraction = new Abstraction('B');
abstraction->Operation();
delete abstraction;
return 0;
}
|
| ○ C版 |
/* Copyright(C) 2009 Yoshinori Oota All rights reserved. */
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
enum COMPONENT_TYPE { CLASS_A ,CLASS_B };
/* Implementor Interface */
struct Implementor {
void (*OperationImp)();
};
struct Implementor* New_Implementor (enum CLASS_TYPE type);
void Delete_Implementor(struct Implementor* implementor);
void ImplementorA_OperationImp();
void ImplementorB_OperationImp();
/* Abstraction Interface */
struct Abstraction {
struct Implementor* imp_;
void (*Operation)(struct Abstraction* pthis);
};
struct Abstraction* New_Abstraction(enum CLASS_TYPE type);
void Delete_Abstraction(struct Abstraction* abs);
void Abstraction_Operation(struct Abstraction* abs);
/* Implementor Class Implementation */
struct Implementor* New_Implementor(enum CLASS_TYPE type) {
struct Implementor* implementor = NULL;
implementor = (struct Implementor*)malloc(sizeof(struct Implementor));
switch(type) {
case CLASS_A:
implementor->OperationImp = &ImplementorA_OperationImp;
break;
case CLASS_B:
implementor->OperationImp = &ImplementorB_OperationImp;
break;
}
return implementor;
}
void Delete_Implementor(struct Implementor* implementor) {
if (implementor != NULL) {
return;
}
free(implementor);
implementor = NULL;
return;
}
void ImplementorA_OperationImp() {
printf("Call ImplementorA::OperationImp\n");
return;
}
void ImplementorB_OperationImp() {
MessageBox(0, "Call ImplementorB::OperationImp\n", "Bridge Sample", MB_OK|MB_SETFOREGROUND);
return;
}
/* Abstraction Class Implementation */
struct Abstraction* New_Abstraction(enum CLASS_TYPE type) {
struct Abstraction* abstraction = NULL;
abstraction = (struct Abstraction*)malloc(sizeof(struct Abstraction));
abstraction->Operation = &Abstraction_Operation;
abstraction->imp_ = New_Implementor(type);
return abstraction;
}
void Delete_Abstraction(struct Abstraction* abstraction) {
if (abstraction != NULL) {
return;
}
Delete_Implementor(abstraction->imp_);
free(abstraction);
abstraction = NULL;
return;
}
void Abstraction_Operation(struct Abstraction* pthis) {
pthis->imp_->OperationImp();
return;
}
int main() {
struct Abstraction* abstraction = NULL;
abstraction = New_Abstraction(CLASS_A);
abstraction->Operation(abstraction);
Delete_Abstraction(abstraction);
abstraction = New_Abstraction(CLASS_B);
abstraction->Operation(abstraction);
Delete_Abstraction(abstraction);
return 0;
}
|
|
改訂履歴
|
2004.11.20 |
鳥の夢さんのご指摘により、C++のAbstractionクラスのデストラクタでimp_のdelete忘れを修正 |
| |
2009.2.21 |
C言語版を追加 |
| |
|
|
|