2年生デザインモード構造パレット
21184 ワード
Adapter
クラスのインタフェースをユーザが望む他のインタフェースのモードに変換し、互換性のないインタフェースのために一緒に動作できないクラスを一緒に動作させる
例
UML
Target class(existing system)
Adaptee class(additional system)
Adapter class
client -> Adapter(Request) -> Adaptee(SpecificReqest)
C++のみ複数継承可能
#include<iostream>
#include<string>
using namespace std;
class Target {
public:
virtual void Request() {
cout << "Existing Service" << endl;
}
};
class Adaptee {
public:
void SpecificRequest() {
cout << "Added Service" << endl;
}
};
class Adapter : public Target {
private:
Adaptee* adaptee_;
public:
Adapter(Adaptee* adaptee) : adaptee_(adaptee) {}
void Request() {
this->adaptee_->SpecificRequest();
}
};
int main() {
Target* target = new Target;
target->Request();
Adaptee* adaptee = new Adaptee;
Adapter* adapter = new Adapter(adaptee);
adapter->Request();
return 0;
}
欠点:追加のサービスレベルが多ければ多いほど複雑になります.
->主に既存のclassが十分に大きく、変更が困難な場合に使用される
Bridge
実装部分から抽象層を離れ,それぞれ独立して変形させるモード
例
type1 : existing class
継承を使用しない
UML
抽象クラスとImplementorクラスは相互継承の関係ではありません
#include<iostream>
#include<string>
using namespace std;
class Implementation {
public:
virtual void print() = 0;
};
class Abstraction {
protected:
Implementation* implementation_;
public:
Abstraction(Implementation* implementation) : implementation_(implementation) { }
virtual void Operation() {
cout << "Caffeine: ";
this->implementation_->print();
}
};
class ExtendedAbstraction : public Abstraction {
public:
ExtendedAbstraction(Implementation* implementation) : Abstraction(implementation) { }
void Operation() {
cout << "Decaf: ";
this->implementation_->print();
}
};
class ConcreteImplementationA : public Implementation {
public:
void print() {
cout << "Hot" << endl;
}
};
class ConcreteImplementationB : public Implementation {
public:
void print() {
cout << "Iced" << endl;
}
};
int main() {
Implementation* implementation = new ConcreteImplementationA;
Abstraction* abstraction = new Abstraction(implementation);
abstraction->Operation();
implementation = new ConcreteImplementationB;
abstraction = new ExtendedAbstraction(implementation);
abstraction->Operation();
return 0;
}
composite
オブジェクト間の関係をツリー構造に整理し、階層全体のパターンを部分的に表すことで、ユーザーが単一のオブジェクトと複合オブジェクトを同時に処理できるようにします.
例
再帰モードを持つシェイプ
UML
![]( https://media.vlpt.us/images/sgh9702/post/ff26563f-a415-4f8e-ac85-afac16 419277/1.PNG)
#include<iostream>
#include <list>
using namespace std;
class Component {
protected:
Component* parent_;
public:
void SetParent(Component* parent) {
this->parent_ = parent;
}
Component* GetParent() const {
return this->parent_;
}
virtual void Add(Component* component) {}
virtual bool IsComposite() {
return false;
}
virtual string Operation() = 0;
};
class Leaf : public Component {
public:
string Operation() {
return "Leaf";
}
};
class Composite : public Component {
protected:
list<Component*> children_;
public:
void Add(Component* component) {
this->children_.push_back(component);
component->SetParent(this);
}
bool IsComposite() {
return true;
}
string Operation() {
std::string result;
for (Component* c : children_) {
if (c == children_.back()) result += c->Operation();
else result += c->Operation() + "+";
}
return "Branch(" + result + ")";
}
};
int main() {
Component *c0 = new Composite;
Component* l1 = new Leaf;
Component* c1 = new Composite;
c0->Add(l1);
c0->Add(c1);
cout << c0->Operation() << endl;
return 0;
}
Decorator
特定の状況と用途に応じて、オブジェクトに責任を追加するモードは、拡張機能が必要な場合にサブクラスを代替する柔軟な代替案となります.
例
UML
ConcreteComponent : basic object
#include<iostream>
#include <list>
using namespace std;
class Component {
public:
virtual string Operation() = 0;
};
class ConcreteComponent : public Component {
public:
string Operation() {
return "Coffee";
}
};
class Decorator : public Component {
protected:
Component* component_;
public:
Decorator(Component* component) : component_(component) { }
string Operation() {
return this->component_->Operation();
}
};
class ConcreteDecoratorA : public Decorator {
public:
ConcreteDecoratorA(Component* component) : Decorator(component) { }
string Operation() {
return "syrup1 + (" + Decorator::Operation()+ ")";
}
};
class ConcreteDecoratorB : public Decorator {
public:
ConcreteDecoratorB(Component* component) : Decorator(component) {
}
string Operation() {
return "syrup2 + (" + Decorator::Operation()+ ")";
}
};
int main() {
Component* coffee = new ConcreteComponent;
coffee = new ConcreteDecoratorA(coffee); //syrup1 added
coffee = new ConcreteDecoratorA(coffee); //syrup1 added
coffee = new ConcreteDecoratorB(coffee); //syrup2 added
coffee = new ConcreteDecoratorB(coffee); //syrup2 added
coffee = new ConcreteDecoratorB(coffee); //syrup2 added
cout << "RESULT: " << coffee->Operation();
return 0;
}
Facade
サブシステムを使いやすくする高度なインタフェースを定義します.
例
UML
#include<iostream>
#include <list>
#include<string>
using namespace std;
class Subsystem1 {
public:
string init() { return "Subsystem1: Init!\n"; }
string run() { return "Subsystem1: On!\n"; }
};
class Subsystem2 {
public:
string init() { return "Subsystem2: Init!\n"; }
string run() { return "Subsystem2: On!\n"; }
};
class Facade{
protected:
Subsystem1* subsystem1_;
Subsystem2* subsystem2_;
public:
Facade(Subsystem1* subsystem1, Subsystem2* subsystem2) {
this->subsystem1_ = new Subsystem1();
this->subsystem2_ = new Subsystem2();
}
string Operation() {
string result = "Initializing subsystems:\n";
result += this->subsystem1_-> init();
result += this->subsystem2_-> init();
result += "Ready to use: \n";
result += this->subsystem1_->run();
result += this->subsystem2_->run();
return result;
}
};
int main() {
Subsystem1* subsystem1 = new Subsystem1;
Subsystem2* subsystem2 = new Subsystem2;
Facade* facade = new Facade(subsystem1, subsystem2);
cout << facade->Operation();
return 0;
}
利点:サブシステムの複雑さからコードを分離できる欠点:アプリケーションのすべてのクラスに結合されたgodオブジェクトです.
Flyweight
同じオブジェクトまたは類似オブジェクト間でできるだけ多くのデータを共有および使用することで、メモリ使用量を最小限に抑えるモード
例
UML
#include<iostream>
#include <list>
#include<string>
#include<unordered_map>
using namespace std;
struct SharedState
{
string type_, color_;
SharedState(const string& type, const string& color)
: type_(type), color_(color) { }
friend ostream& operator<<(ostream& os, const SharedState& ss)
{
return os << "[ " << ss.type_ << " , " << ss.color_ << " ]";
}
};
struct UniqueState
{
string price_;
UniqueState(const string& price) : price_(price) { }
friend ostream& operator<<(std::ostream& os, const UniqueState& us)
{
return os << "[ " << us.price_ << " ]";
}
};
class Flyweight
{
private:
SharedState* shared_state_;
public:
Flyweight(const SharedState* shared_state) : shared_state_(new SharedState(*shared_state)) { }
Flyweight(const Flyweight& other) : shared_state_(new SharedState(*other.shared_state_)) { }
SharedState* shared_state() const { return shared_state_; }
void Operation(const UniqueState& unique_state) const
{
cout << "Flyweight: Displaying shared (" << *shared_state_
<< ") and unique (" << unique_state << ") state." << endl;
}
};
class FlyweightFactory
{
private:
unordered_map<string, Flyweight> flyweights_;
string GetKey(const SharedState& ss) const { return ss.type_ + "_" + ss.color_; }
public:
FlyweightFactory(std::initializer_list<SharedState> share_states)
{
for (const SharedState& ss : share_states)
this->flyweights_.insert(make_pair<string, Flyweight>(this->GetKey(ss), Flyweight(&ss)));
}
Flyweight GetFlyweight(const SharedState& shared_state)
{
string key = this->GetKey(shared_state);
if (this->flyweights_.find(key) == this->flyweights_.end())
this->flyweights_.insert(make_pair(key, Flyweight(&shared_state)));
return this->flyweights_.at(key);
}
void ListFlyweights() const
{
size_t count = this->flyweights_.size();
for (pair<string, Flyweight> pair : this->flyweights_) cout << pair.first << "\n";
}
};
void AddItem(
FlyweightFactory& ff, const string& price,
const string& type, const string& color)
{
cout << "Adding an item to DB." << endl;;
const Flyweight& flyweight = ff.GetFlyweight({ type, color });
flyweight.Operation({ price });
}
int main()
{
FlyweightFactory* factory = new FlyweightFactory({ {"Americano", "black" }, { "Mocha", "white" } });
factory->ListFlyweights();
AddItem(*factory, "5000", "Americano", "black");
AddItem(*factory, "6000", "Mocha", "white");
AddItem(*factory, "4000", "Espresso", "black");
factory->ListFlyweights();
return 0;
}
欠点:コードがより複雑になる
Proxy
エージェントはクラスで、他のもののインタフェースを接続する役割を果たしています.
例
UML
#include<iostream>
#include <list>
#include<string>
using namespace std;
class Subject {
public:
virtual void Request() const = 0;
};
class RealSubject : public Subject {
public:
void Request() const {
cout << "Handling Request." << endl;
}
};
class Proxy : public Subject {
private:
RealSubject* real_subject_;
bool CheckAccess() const {
cout << "Proxy: Checking Access" << endl;
return true;
}
public:
Proxy(RealSubject* real_subject) : real_subject_(new RealSubject(*real_subject)) { }
void Request() const override {
if (this->CheckAccess()) {
cout << "Proxy: Access Granted" << endl;
this->real_subject_->Request();
}
}
};
int main() {
RealSubject* real_subject = new RealSubject;
Proxy* proxy = new Proxy(real_subject);
proxy->Request();
return 0;
}
長所
短所
Reference
この問題について(2年生デザインモード構造パレット), 我々は、より多くの情報をここで見つけました https://velog.io/@sgh9702/2학년-디자인-패턴テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol