C++とUMLのクラス図
増補改訂版Java言語で学ぶデザインパターン入門のUMLのクラス図で
- 継承
- 集約
- インターフェース
- 関連
- Uses
- Creates
- Notifies
ぐらいしか使っていないんだけど、自分の場合はほとんどのクラス図でこれで十分なような気がしてきた。
継承
// -*- coding: utf-8-unix -*- digraph inherit { graph [fontname = "monospace", fontsize = 10, rankdir = TD]; node [fontname = "monospace", fontsize = 10]; edge [fontname = "monospace", fontsize = 10]; // node node [shape = record]; vehicle_class [label = "{Vehicle||}"]; car_class [label = "{Car||}"]; vehicle [label = "class Vehicle"]; car [label = "class Car : Vehicle"]; // edge edge [arrowhead = none, arrowtail = onormal]; vehicle_class -> car_class; vehicle -> car; // rank {rank = same; car_class; car} {rank = same; vehicle_class; vehicle} }
集約
車(Car)は、車輪(Wheel)のインスタンスを持つ。
// -*- coding: utf-8-unix -*- digraph aggregation { graph [fontname = "monospace", fontsize = 10, rankdir = TD]; node [fontname = "monospace", fontsize = 10]; edge [fontname = "monospace", fontsize = 10]; // node node [shape = record]; car_class [label = "{Car||}"]; wheel_class [label = "{Wheel||}"]; car [label = "class Car \{\l Wheel wheel[];\l\}\l"]; wheel [label = "class Wheel"]; // edge edge [arrowhead = none, arrowtail = odiamond, label = "1 .. n"]; car_class -> wheel_class; car -> wheel; // rank {rank = same; car_class; car} {rank = same; wheel_class; wheel} }
インターフェース
運転できるもの(Driable)は、発進l(run)と停止(stop)ができる。どう実現するかサブクラスが定義しなければならない。
// -*- coding: utf-8-unix -*- digraph interface { graph [fontname = "monospace", fontsize = 10, rankdir = TD]; node [fontname = "monospace", fontsize = 10]; edge [fontname = "monospace", fontsize = 10]; // node node [shape = record]; drivable_class [label = "{\<\<interface\>\>\nDrivable||run()\lstop()\l}"]; drive_class [label = "{Drive||run()\lstop()\l}"]; drivable [label = "\ class Drivable \{ \l\ virtual run(); \l\ virtual stop(); \l\ \} \l\ "]; drive [label = "\ class Drive : Drivable \{ \l\ run() \{/* */\}; \l\ stop() \{/* */\}; \l\ \} \l\ "]; // edge edge [arrowhead = none, arrowtail = onormal, style = dashed]; drivable_class -> drive_class; drivable -> drive; // rank {rank = same; drivable_class; drivable} {rank = same; drive_class; drive} }
関連
Uses
描画クラス(Draw)は波を書くとき、Mathクラスのsin()を使う。
// -*- coding: utf-8-unix -*- digraph relation_use { graph [fontname = "monospace", fontsize = 10, rankdir = TD, nodesep = 0.5]; node [fontname = "monospace", fontsize = 10]; edge [fontname = "monospace", fontsize = 10]; // node node [shape = record]; draw_class [label = "{Draw||draw_wave()}"]; math_class [label = "{Math||sin()\l}"]; draw [label = "\ class Draw \{ \l\ draw_wave() \{ \l\ Math m; \l\ m.sin(); \l\ ... \l\ \} \l\ \} \l\ "]; math [label = "\ class Math \{ \l\ sin() \{/* */\}; \l\ \} \l\ "]; // edge edge [arrowhead = vee, arrowtail = none]; draw_class -> math_class [taillabel = "Uses\>", labelangle = 10, labeldistance = 6]; draw -> math [label = "Uses\>"]; edge [arrowhead = none, arrowtail = none, style = invis, label = ""]; draw_class -> draw; math_class -> math; // rank {rank = same; draw_class; math_class} {rank = same; draw; math} }
Creates
// -*- coding: utf-8-unix -*- digraph relation_create { graph [fontname = "monospace", fontsize = 10, rankdir = TD, nodesep = 0.5]; node [fontname = "monospace", fontsize = 10]; edge [fontname = "monospace", fontsize = 10]; // node node [shape = record]; chef_class [label = "{Chef||cook()\l}"]; dish_class [label = "{Dish||}"]; chef [label = "\ class Chef \{ \l\ cook() \{ \l\ Dish dish = new Dish; \l\ ... \l\ \} \l\ \} \l\ "]; dish [label = "class Dish"]; // edge edge [arrowhead = vee, arrowtail = none]; chef_class -> dish_class [taillabel = "Creates\>", labelangle = 10, labeldistance = 6]; chef -> dish [label = "Creates\>"]; edge [arrowhead = none, arrowtail = none, style = invis, label = ""]; chef_class -> chef; dish_class -> dish; // rank {rank = same; chef_class; dish_class} {rank = same; chef; dish} }
Notifies
// -*- coding: utf-8-unix -*- digraph relation_notify { graph [fontname = "monospace", fontsize = 10, rankdir = TD, nodesep = 0.5]; node [fontname = "monospace", fontsize = 10]; edge [fontname = "monospace", fontsize = 10]; // node node [shape = record]; client_class [label = "{Client||call_taxi()\l}"]; taxi_class [label = "{Taxi||}"]; client [label = "\ class Client \{ \l\ call_taxi() \{ \l\ Message message; \l\ message.number = TAXI; \l\ message.send(); \l\ \} \l\ \} \l\ "]; taxi [label = "class Taxi"]; // edge edge [arrowhead = vee, arrowtail = none]; client_class -> taxi_class [taillabel = "Notifies\>", labelangle = 10, labeldistance = 6]; client -> taxi [label = "Notifies\>"]; edge [arrowhead = none, arrowtail = none, style = invis, label = ""]; client_class -> client; taxi_class -> taxi; // rank {rank = same; client_class; taxi_class} {rank = same; client; taxi} }