#質問
書籍「ThoughtWorksアンソロジー」の「第5章 オブジェクト指向エクササイズ」
上記書籍自体はまだ未購入で読んでおりませんが、ネット上でこの本で紹介されている「オブジェクト指向エクササイズ」について触れているページを幾つか見て気になっていたので実践してみました。
実践してみたのは良いのですが、なんだか良くわからなくなってしまいました。
「よくわからなくなった」という部分が質問箇所でして、いかに掲載するコードのコメントに記載しておりますので、そちらのコメントを参照頂けると幸いです。
以下のコードでは「オブジェクト指向エクササイズ」の以下の2つのルールを実践したつもりです。
別質問で立てている「円クラスをMVC的に実装したいです!」のコードをリファクタリングする目的で練習がてらに取り組んでみました。
コード
コード内のコメントで「Q:」が先頭についているコメント箇所が自分が特におかしくないか気になっている箇所です。
アドバイス頂けると大変ありがたいです!
TypeScript
1class Circle { 2 3 private point: Point; 4 private radius: Length; 5 6 constructor(point: Point, radius: Length) { 7 this.point = point; 8 this.radius = radius; 9 } 10 11 //左上を起点としたxy座標を返す 12 get position() { 13 return this.point.cordinates; 14 } 15 16 //円の中心を起点としたxy座標を返す 17 get centerPosition() { 18 var positionAtLeftTop = this.point.cordinates; 19 20 //Q.ここは新しいPointクラスのインスタンスを生成して返すべきですか??? 21 return {x: positionAtLeftTop.x.value + this.radius.value, y: positionAtLeftTop.y.value + this.radius.value}; 22 } 23 24} 25 26 27class Point { 28 29 private x: Cordinate; 30 private y: Cordinate; 31 32 constructor(x: Cordinate, y: Cordinate) { 33 this.x = x; 34 this.y = y; 35 } 36 37 get cordinates() { 38 return {x: this.x, y: this.y}; 39 } 40 41 42 43} 44 45class Cordinate { 46 47 private cordinate: number; 48 constructor(value: number) { 49 this.cordinate = value; 50 } 51 52 get value() { 53 return this.cordinate; 54 } 55 56} 57 58 59 60class Length { 61 62 private length: number; 63 constructor(value: number) { 64 this.length = value; 65 } 66 67 get value() { 68 return this.length; 69 } 70 71} 72 73//Q.依存性の注入を愚直にすると、引数がこんなことになってしまうのですが大丈夫でしょうか? 74var circle = new Circle(new Point(new Cordinate(10), new Cordinate(10)), new Length(10));
追記
とりあえず、今回試した2つのルールを実践した結果、小さなクラスが結果的に出来上がりましたが、そのおかけで自然と「座標に関する振る舞いはCordinateクラスでしよう」とか、そういった発想が生まれやすいなという実感はありました。
flied_onionさんへの返答
LengthをCordinateから生成できない気がするんですが、Lengthは2つのCordinateで求められるべきじゃないかな、と。
Cordinateが「二次元の原点座標からの距離」と考えるならLengthもCordinateでいいような気もしてます。
円の半径をLength型で表していますが、Lengthを2点の座標から表すことにすると円の半径をどう表したら良いのでしょう。
円の中心点と外周を結ぶ線が半径ですから、円の半径をLength型で定義するためには円の中心点がまずxy座標ではどこで、そして、外周上の点はx, y座標のどこにするかを決めないと半径を出せないと思うので、なんだか小難しいですね。。。
そうすべきものなのでしょうか?
Lineクラスみたいなものであれば、初期化時に始点、終点を決めて生成するというのは納得です。
Q.ここは新しいPointクラスのインスタンスを生成して返すべきですか???
逆に聞きますが、Pointでないならそれは何を返してるんですか?
それ(設計)次第かと。
メソッドの戻り値を何にして呼び出し元に渡すかは確かにケースバイケースですよね。
単純にxy座標だけ知りたければ、{x: 10, y: 10}みたいな戻り値で十分であるということですよね。
少なくともpositionとcenterPositionは同じ物を返した方が一貫性があっていいと思います。
これは本当ですね! ここは統一すべきだと感じました。ありがとうございます。
私にはこれが依存性の注入に見えませんでした(元がプリミティブだからかな)。
前はCircle内のPointをコンストラクタに渡されたx,yでコンストラクタの中でnewしてたのを、
Pointを受け取るようにして解消したってことでしょうか?
その通りです! 別質問で詳しく投稿しています。
https://teratail.com/questions/44223
今はCordinateクラスもLengthクラスもPointクラスも特にメソッドらしいメソッドがないですが、長さの単位変換をLengthクラスが行ったり、座標変換をPointクラスが行ったりとなるのかなと思っています。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/08/14 11:26
2016/08/15 03:53