質問編集履歴
2
参考URLと内容の追加
title
CHANGED
File without changes
|
body
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
こういった場合に、開放閉鎖原則を守りながらクラス設計をするにはどうしたらよいでしょうか?
|
9
9
|
|
10
10
|
|
11
|
-
※追記
|
11
|
+
※追記1
|
12
12
|
至らぬ点が多々あり、申し訳ございません。
|
13
13
|
|
14
14
|
「これは変更の理由ごとにクラスを分割することで、新たな仕様追加には新たなクラスを増やすことで対応するというものだと解釈しました。」
|
@@ -101,4 +101,22 @@
|
|
101
101
|
|
102
102
|
回避策として、例えばMonsterAに対してMonsterAScoreクラスを作成して処理を委譲することを考えたのですが、そうするとキャラクターが増えるごとにいくつものクラスを作成しなければいけなくなります。
|
103
103
|
|
104
|
-
どのようにアプローチすればよいでしょうか。
|
104
|
+
どのようにアプローチすればよいでしょうか。
|
105
|
+
|
106
|
+
|
107
|
+
|
108
|
+
|
109
|
+
|
110
|
+
※追記2
|
111
|
+
|
112
|
+
[開発者が知っておくべきSOLIDの原則](https://postd.cc/solid-principles-every-developer-should-know/)
|
113
|
+
[ソフトウェア原則[1] - OCP(Open-Close Principle)](http://objectclub.jp/technicaldoc/object-orientation/principle/principle01)
|
114
|
+
[Laravelチップシリーズ 2:SOLIDの世界1](https://www.bravesoft.co.jp/blog/archives/2458)
|
115
|
+
|
116
|
+
|
117
|
+
以上のリンク先から、変更の理由=キャラクターの追加と設計段階で予想されるなら、キャラクターをそれぞれ共通のインターフェースを持った別のクラスにすることで既存のクラスの修正を行わなくてよいのが開放閉鎖原則のメリットだと考えておりました。
|
118
|
+
リンク先の内容が全て或いは一部誤っているのか、記載の内容はあっていて私の理解だけが誤っているのか自分には判断できません。
|
119
|
+
申し訳ありませんが、こちらのご指摘からお願いします。
|
120
|
+
|
121
|
+
|
122
|
+
「階層」とはオブジェクトの所持関係のことです。追記1で記述したコードの場合、キャラクタークラスのフィールドのオブジェクトが更に別のフィールドを持ち、その初期化の内容がキャラクターごとなら追記1の通り初期化が複雑で膨大になるのでは?と考えていました。
|
1
内容の訂正とコードの追加
title
CHANGED
File without changes
|
body
CHANGED
@@ -5,4 +5,100 @@
|
|
5
5
|
例えばゲームを設計してるとして、キャラクターが1つ増やすとします。
|
6
6
|
このゲームは、キャラクターごとにいくつもの階層に渡る機能を別に実装する必要があるとします。
|
7
7
|
|
8
|
-
こういった場合に、開放閉鎖原則を守りながらクラス設計をするにはどうしたらよいでしょうか?
|
8
|
+
こういった場合に、開放閉鎖原則を守りながらクラス設計をするにはどうしたらよいでしょうか?
|
9
|
+
|
10
|
+
|
11
|
+
※追記
|
12
|
+
至らぬ点が多々あり、申し訳ございません。
|
13
|
+
|
14
|
+
「これは変更の理由ごとにクラスを分割することで、新たな仕様追加には新たなクラスを増やすことで対応するというものだと解釈しました。」
|
15
|
+
これは解釈以前に内容が伝わる文章になっていませんでした。
|
16
|
+
変更の理由=新たな仕様追加時には新たなクラスを追加するような設計にするという意味です。
|
17
|
+
|
18
|
+
|
19
|
+
想定しているケースの簡単な例を記載します。拙いコードで申し訳ありませんが、ご確認下さい。
|
20
|
+
|
21
|
+
前提条件
|
22
|
+
・キャラクターを採集して点数を競うイベントがある
|
23
|
+
・点数の計算式はキャラクターごとに異なる
|
24
|
+
・点数の計算式は時間帯や曜日によっても異なる
|
25
|
+
|
26
|
+
```C#
|
27
|
+
class Monster
|
28
|
+
{
|
29
|
+
//★モンスターごとに初期化が必要なフィールド
|
30
|
+
//攻撃、防御など複数の戦闘用パラメーター
|
31
|
+
//習得中の技
|
32
|
+
//場所ごとの遭遇率
|
33
|
+
//etc...
|
34
|
+
|
35
|
+
|
36
|
+
//時間帯と曜日により点数を返すメソッド
|
37
|
+
public int GetScore(TimeZone timeZone,Week week)
|
38
|
+
{
|
39
|
+
//省略
|
40
|
+
}
|
41
|
+
|
42
|
+
|
43
|
+
//危惧している点:分岐ごとの処理メソッドが沢山増える
|
44
|
+
private GetScoreByMoning()
|
45
|
+
{
|
46
|
+
//省略
|
47
|
+
}
|
48
|
+
|
49
|
+
private GetScoreByNone()
|
50
|
+
{
|
51
|
+
//省略
|
52
|
+
}
|
53
|
+
|
54
|
+
private GetScoreByNight()
|
55
|
+
{
|
56
|
+
//省略
|
57
|
+
}
|
58
|
+
|
59
|
+
}
|
60
|
+
|
61
|
+
class MonsterList : List<Monster>
|
62
|
+
{
|
63
|
+
//List内のMonsterの点数を合計する
|
64
|
+
public int GetTotalScore()
|
65
|
+
{
|
66
|
+
//省略
|
67
|
+
}
|
68
|
+
|
69
|
+
}
|
70
|
+
|
71
|
+
class Contest
|
72
|
+
{
|
73
|
+
//MonsterListのTotalScoreによりGiftを返す
|
74
|
+
public Gift GetGift(MonsterList monsters)
|
75
|
+
{
|
76
|
+
//省略
|
77
|
+
}
|
78
|
+
|
79
|
+
|
80
|
+
}
|
81
|
+
|
82
|
+
public enum Gift
|
83
|
+
{
|
84
|
+
//省略
|
85
|
+
}
|
86
|
+
|
87
|
+
public enum Week
|
88
|
+
{
|
89
|
+
//省略
|
90
|
+
}
|
91
|
+
|
92
|
+
public enum TimeZone
|
93
|
+
{
|
94
|
+
//省略
|
95
|
+
}
|
96
|
+
```
|
97
|
+
|
98
|
+
問題として考えている点は主に2つになります。
|
99
|
+
・キャラクター固有の特徴を表すフィールドの初期化が複雑で膨大になる
|
100
|
+
・条件分岐ごとのメソッドにより、メソッド数が膨大になる
|
101
|
+
|
102
|
+
回避策として、例えばMonsterAに対してMonsterAScoreクラスを作成して処理を委譲することを考えたのですが、そうするとキャラクターが増えるごとにいくつものクラスを作成しなければいけなくなります。
|
103
|
+
|
104
|
+
どのようにアプローチすればよいでしょうか。
|