質問編集履歴
4
文法の修正
test
CHANGED
File without changes
|
test
CHANGED
@@ -82,7 +82,7 @@
|
|
82
82
|
@abstractmethod
|
83
83
|
def print_shape(self):
|
84
84
|
pass
|
85
|
-
|
85
|
+
@abstractmethod
|
86
86
|
def print_dimension(self):
|
87
87
|
pass
|
88
88
|
|
3
委譲に関する修正
test
CHANGED
File without changes
|
test
CHANGED
@@ -73,14 +73,17 @@
|
|
73
73
|
from abc import ABCMeta, abstractmethod
|
74
74
|
|
75
75
|
|
76
|
-
class Dimension(metaclass=ABCMeta):
|
76
|
+
class Dimension(metaclass=ABCMeta): # 次元のインターフェイス
|
77
77
|
@abstractmethod
|
78
|
-
def print_dimension(self):
|
78
|
+
def print_dimension(self):
|
79
79
|
pass
|
80
80
|
|
81
81
|
class Shape(metaclass=ABCMeta): # 図形のインターフェイス
|
82
82
|
@abstractmethod
|
83
83
|
def print_shape(self):
|
84
|
+
pass
|
85
|
+
|
86
|
+
def print_dimension(self):
|
84
87
|
pass
|
85
88
|
|
86
89
|
|
@@ -93,6 +96,7 @@
|
|
93
96
|
print('This is a 3D object')
|
94
97
|
|
95
98
|
|
99
|
+
|
96
100
|
class Globe(Shape): # 球
|
97
101
|
def __init__(self, dimension):
|
98
102
|
self.dimension = dimension
|
@@ -100,6 +104,10 @@
|
|
100
104
|
def print_shape(self):
|
101
105
|
print('This is a Globe')
|
102
106
|
|
107
|
+
def print_dimension(self):
|
108
|
+
self.dimension.print_dimension()
|
109
|
+
|
110
|
+
|
103
111
|
class Cube(Shape): # 立方体
|
104
112
|
def __init__(self, dimension):
|
105
113
|
self.dimension = dimension
|
@@ -107,16 +115,18 @@
|
|
107
115
|
def print_shape(self):
|
108
116
|
print('This is a Cube')
|
109
117
|
|
110
|
-
|
118
|
+
def print_dimension(self):
|
119
|
+
self.dimension.print_dimension()
|
120
|
+
|
111
121
|
|
112
122
|
if __name__ == '__main__':
|
113
123
|
data = Cube(Dimension2D())
|
114
124
|
data.print_shape()
|
115
|
-
data.
|
125
|
+
data.print_dimension()
|
116
126
|
|
117
127
|
data = Globe(Dimension3D())
|
118
128
|
data.print_shape()
|
119
|
-
data.
|
129
|
+
data.print_dimension()
|
120
130
|
```
|
121
131
|
### 補足情報(FW/ツールのバージョンなど)
|
122
132
|
python 3.8.10
|
2
修正コードの追加
test
CHANGED
File without changes
|
test
CHANGED
@@ -66,7 +66,58 @@
|
|
66
66
|
|
67
67
|
# これをif文を使わずに同じ結果を得たい
|
68
68
|
```
|
69
|
+
### 修正コード
|
70
|
+
回答で提案していただいた、委譲を使って書き直しました。
|
71
|
+
これが正しい使い方なのか、もっとうまく書く方法があるかなど、ご指摘いただければと思います。
|
72
|
+
```python
|
73
|
+
from abc import ABCMeta, abstractmethod
|
69
74
|
|
75
|
+
|
76
|
+
class Dimension(metaclass=ABCMeta):
|
77
|
+
@abstractmethod
|
78
|
+
def print_dimension(self): # 次元のインターフェイス
|
79
|
+
pass
|
80
|
+
|
81
|
+
class Shape(metaclass=ABCMeta): # 図形のインターフェイス
|
82
|
+
@abstractmethod
|
83
|
+
def print_shape(self):
|
84
|
+
pass
|
85
|
+
|
86
|
+
|
87
|
+
class Dimension2D(Dimension): # 2Dの次元
|
88
|
+
def print_dimension(self):
|
89
|
+
print('This is a 2D object')
|
90
|
+
|
91
|
+
class Dimension3D(Dimension): # 3Dの次元
|
92
|
+
def print_dimension(self):
|
93
|
+
print('This is a 3D object')
|
94
|
+
|
95
|
+
|
96
|
+
class Globe(Shape): # 球
|
97
|
+
def __init__(self, dimension):
|
98
|
+
self.dimension = dimension
|
99
|
+
|
100
|
+
def print_shape(self):
|
101
|
+
print('This is a Globe')
|
102
|
+
|
103
|
+
class Cube(Shape): # 立方体
|
104
|
+
def __init__(self, dimension):
|
105
|
+
self.dimension = dimension
|
106
|
+
|
107
|
+
def print_shape(self):
|
108
|
+
print('This is a Cube')
|
109
|
+
|
110
|
+
|
111
|
+
|
112
|
+
if __name__ == '__main__':
|
113
|
+
data = Cube(Dimension2D())
|
114
|
+
data.print_shape()
|
115
|
+
data.dimension.print_dimension()
|
116
|
+
|
117
|
+
data = Globe(Dimension3D())
|
118
|
+
data.print_shape()
|
119
|
+
data.dimension.print_dimension()
|
120
|
+
```
|
70
121
|
### 補足情報(FW/ツールのバージョンなど)
|
71
122
|
python 3.8.10
|
72
123
|
IED: Spyder IDE 5.4.0
|
1
質問をより具体化、およびコードの修正
test
CHANGED
File without changes
|
test
CHANGED
@@ -1,46 +1,70 @@
|
|
1
1
|
### 前提
|
2
2
|
|
3
3
|
プログラミングの初心者です。
|
4
|
-
多重のif文が
|
4
|
+
多重のif文があるコードを、オブジェクト指向で書き直すには、
|
5
5
|
どういった書き方をすれば良いでしょうか?
|
6
|
-
|
6
|
+
|
7
|
-
|
7
|
+
コード例では3Dと2Dのそれぞれの球形、直方体をオブジェクトとして持ちたいです。
|
8
|
+
現段階では図形に依存するshape.print_shape()の命令を、オブジェクトが自身の図形を知っているのでポリモーフィズムの実現によってメソッドを切り替えられますが、次元は変数として持っていなければならず、次元を増やしたときにif文の改定が必要になるのでメンテナンス性に欠けます。(特に大量にクラスがあった場合すべてのif文に修正が必要)
|
9
|
+
|
10
|
+
->if文を使わずに次元の判断をメンテナンス性を維持した状態で付け加えたいです。
|
8
|
-
|
11
|
+
またはオブジェクト指向の考え方そのものや、構造がおかしいのであれば指摘していただきたいです。
|
12
|
+
|
9
13
|
### 実現したいこと
|
10
14
|
”もし3Dデータであり、球体であるなら~”
|
11
|
-
”もし
|
15
|
+
”もし2Dデータであり、直方体であるなら~”
|
12
|
-
をオブジェクト指向で表現
|
16
|
+
をif文を使わずにオブジェクト指向で表現したい。
|
13
17
|
|
14
18
|
### 該当のソースコード
|
15
19
|
```python
|
20
|
+
from abc import ABCMeta, abstractmethod
|
16
21
|
|
17
|
-
from abc import ABCMeta, abstractmethod
|
18
|
-
class
|
22
|
+
class Shape(metaclass=ABCMeta): # 図形のインターフェイス
|
19
23
|
@abstractmethod
|
20
|
-
def print_
|
24
|
+
def print_shape(self):
|
21
25
|
pass
|
22
26
|
|
27
|
+
def print_dimension(self):
|
28
|
+
pass
|
29
|
+
|
30
|
+
|
23
|
-
class Globe
|
31
|
+
class Globe(Shape):
|
32
|
+
def __init__(self, dimension):
|
33
|
+
self.dimension = dimension
|
34
|
+
|
24
|
-
def print_
|
35
|
+
def print_shape(self):
|
25
36
|
print('This is a Globe')
|
26
37
|
|
38
|
+
def print_dimension(self):
|
39
|
+
if self.dimension == 3:
|
40
|
+
print('This is a 3D object')
|
41
|
+
elif self.dimension == 2:
|
42
|
+
print('This is a 2D object')
|
43
|
+
|
27
|
-
class Cube
|
44
|
+
class Cube(Shape):
|
45
|
+
def __init__(self, dimension):
|
46
|
+
self.dimension = dimension
|
47
|
+
|
28
|
-
def print_
|
48
|
+
def print_shape(self):
|
29
49
|
print('This is a Cube')
|
30
50
|
|
31
|
-
class Globe2D(Data3D): # 2Dの図形
|
32
|
-
def print_d
|
51
|
+
def print_dimension(self):
|
52
|
+
if self.dimension == 3:
|
33
|
-
print('This is a
|
53
|
+
print('This is a 3D object')
|
54
|
+
elif self.dimension == 2:
|
55
|
+
print('This is a 2D object')
|
34
56
|
|
35
|
-
class Cube2D(Data3D): # 2Dの図形
|
36
|
-
def print_data(self):
|
37
|
-
print('This is a part of a cube')
|
38
|
-
|
39
|
-
# せっかく2Dと3Dでグループがあるのに、同じようなクラスが永遠と並んでしまいます。
|
40
57
|
|
41
58
|
if __name__ == '__main__':
|
42
|
-
|
59
|
+
data = Cube(2)
|
43
|
-
|
60
|
+
data.print_shape()
|
61
|
+
data.print_dimension()
|
62
|
+
|
63
|
+
data = Globe(3)
|
64
|
+
data.print_shape()
|
65
|
+
data.print_dimension()
|
66
|
+
|
67
|
+
# これをif文を使わずに同じ結果を得たい
|
44
68
|
```
|
45
69
|
|
46
70
|
### 補足情報(FW/ツールのバージョンなど)
|