Proxy

Proxyパターンは、代理人(Proxy)でもできる処理は代理人が処理し、できない処理は本体が行うような構造。

21.Proxyパターン | TECHSCORE(テックスコア)

main.cppで、

class_proxy_printのコンストラクタに渡したclass_simple_printはnewで生成しているが、deleteがない。
実は、class_proxy_printの中でメンバとしていて、デストラクタでdeleteしているのである。
class_proxy_printは演算子オーバーロードなどで、実質的にclass_simple_printのポインタのような役割となっている。
このようなものをスマートポインタといい、このスマートポインタの元になっている仕組みがProxyパターン。

$ vi main.cpp 
$ g++ -o main main.cpp simple_print.cpp proxy_print.cpp simple_print_factory.cpp 
$ ./main 
ABCDE
FGHIJ
KLM
NOP
VWXYZ
delete simple_print_
delete simple_print_
$

class_simple_printは破棄されている。

Sample/designpattern/proxy/proxy/src/proxy at master · bg1bgst333/Sample · GitHub

Flyweight

Flyweightパターンは、既に生成したインスタンスと実質同じであれば、新たに生成せず、他のインスタンスと共有することでリソースを無駄なく使うような構造。

20.Flyweight パターン | TECHSCORE(テックスコア)

main.cppで、

"ABCDE"を2回、"XYZ"を1回、取得しているが、

$ vi main.cpp 
$ g++ -o main main.cpp framed_string.cpp framed_string_factory.cpp 
$ ./main 
create ABCDE frame
*******
*ABCDE*
*******
get ABCDE frame
*******
*ABCDE*
*******
create XYZ frame
*****
*XYZ*
*****
$

2回目の"ABCDE"は1回目の文字列を取得しているだけで、生成はしていない。

Sample/designpattern/flyweight/flyweight/src/flyweight at master · bg1bgst333/Sample · GitHub

State

Stateパターンでは、状態を定数リテラルなどで表すのではなく、クラスとして表すようにする。

19.State パターン | TECHSCORE(テックスコア)

main.cppで、

定数リテラルだと、class_nostate_timezoneの中でif文が大量になり、分岐処理が大変だが、class_state_timezoneだとif文が無いのですっきりする。

$ vi main.cpp 
$ g++ -o main *.cpp
$ ls
afternoon_timezone.cpp      evening_timezone.h     nostate_timezone.cpp
afternoon_timezone.h        main                   nostate_timezone.h
daytime_timezone.cpp        main.cpp               rough_timezone.cpp
daytime_timezone.h          midnight_timezone.cpp  rough_timezone.h
detailed_timezone.cpp       midnight_timezone.h    state_timezone.cpp
detailed_timezone.h         morning_timezone.cpp   state_timezone.h
early_morning_timezone.cpp  morning_timezone.h     timezone.h
early_morning_timezone.h    night_timezone.cpp
evening_timezone.cpp        night_timezone.h
[h.miura@localhost state]$ ./main 
timezone->get_timezone_str(20) = afternoon
timezone->get_timezone_str(20) = night
timezone2->get_timezone_str(20) = afternoon
timezone3->get_timezone_str(20) = night
$

処理は変わらないが。

Sample/designpattern/state/state/src/state at master · bg1bgst333/Sample · GitHub

Memento

どこかでインスタンスのスナップショットを取っておき、いざというときにその状態を復元するような仕組みをMementoパターンという。

18.Memento パターン | TECHSCORE(テックスコア)

main.cppで、

state->printで値を出力、state->nextで次の処理に進める。
途中、state->create_mementoでスナップショットmementoを作っておいて、一方で処理自体は進める。
state->set_mementoで取っておいたmementoをセットすると、その時の状態に戻る。

$ vi main.cpp 
$ g++ -o main main.cpp memento.cpp state.cpp 
$ ./main 
value_ = 0
value_ = 1
value_ = 2
value_ = 3
value_ = 4
value_ = 5
value_ = 3
$

mementoを取った時の3に戻っている。

Sample/designpattern/memento/memento/src/memento at master · bg1bgst333/Sample · GitHub

Observer

被観測者の状態が変化したら、観測者(Observer)に状態の変化があったことを通知するような構造をObserverパターンという。

17.Observer パターン | TECHSCORE(テックスコア)

main.cppで、

staff1に10、staff2に20、staff3に30をセットしてる。

$ vi main.cpp 
$ g++ -o main main.cpp manager.cpp staff.cpp 
$ ./main 
staff1 value_ = 10
staff2: staff1 changed!
staff3: staff1 changed!
staff2 value_ = 20
staff1: staff2 changed!
staff3: staff2 changed!
staff3 value_ = 30
staff1: staff3 changed!
staff2: staff3 changed!
$

staff1に10をセットされると、staff2, staff3に通知されて、"staff1 changed!"と出力。
他のstaffで値がセットされても、それ以外のstaffに通知される。

Sample/designpattern/observer/observer/src/observer at master · bg1bgst333/Sample · GitHub

Mediator

複数のオブジェクト間の調整役となるオブジェクトを置くような構造をMediatorパターンという。

16.Mediator パターン | TECHSCORE(テックスコア)

main.cppで、

managerが調整役(Mediator)となり、3つのstaffを調整する。
最初はstaff3つとも値を0にしておいて、staff1からstaff3まで順に値を1にしていく。

$ vi main.cpp 
$ g++ -o main main.cpp manager.cpp staff.cpp 
$ ./main 
staff1 value_ = 0
staff2 value_ = 0
staff3 value_ = 0
0, 0, 0
staff1 value_ = 1
1, 0, 0
staff2 value_ = 1
staff1 value_ = 0
0, 1, 0
staff3 value_ = 1
staff2 value_ = 0
0, 0, 1
$

staff1に1をセットするのはいいとして、staff2に1をセットすると、同時にstaff1は0に戻る。
staff3に1をセットすると、同時にstaff2は0に戻る。
このように、2つ以上が1にならないように調整している。

Sample/designpattern/mediator/mediator/src/mediator at master · bg1bgst333/Sample · GitHub

Facade

複数のクラスを組み合わせて処理を行う時に、その窓口となるクラスを作って、そこを経由していろいろなクラスの処理を行うようにする構造をFacadeパターンという。

15.Facadeパターン | TECHSCORE(テックスコア)

main.cppで、

class_front::searchは窓口であり、実際には中で別のクラスが処理をしている。

$ vi main.cpp 
$ g++ -o main main.cpp front.cpp  data_list.cpp ng_list.cpp 
$ ./main 
data1 OK!
data1 exist and valid!
data10 not found!
data3 NG!
$

data1はあり、data10はない。NGリストがあって、data3はNGリストにあったので、NGとなっている。

Sample/designpattern/facade/facade/src/facade at master · bg1bgst333/Sample · GitHub