TypeScriptでオブジェクト指向実践 その①
オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方
を読んでいるのでメモがてらにまとめてみる。
RubyではなくTypeScriptで実装してみた。
モデル
1. 変数を隠蔽する
変数をprivateにし、外部からの取得はgetterにする。これにより直接変数がいじられることを防げるのと、プライベート変数に追加で1.2倍係数を掛けたいなどの要望があった時はgetter内をいじるだけでよい。
export class Gear {
private PI = 3.14;
constructor(private _chainring: number, private _cog: number,private _rim: number, private _tire: number) {
}
get rim() {
return this._rim;
}
get tire() {
return this._tire;
}
get cog(): number {
return this._cog;
}
get chainring() {
return this._chainring;
}
diameter() {
return this.rim + this.tire * 2;
}
public ratio(): number {
return this.chainring / this.cog
}
public gearInches() {
return this.ratio() * this.diameter();
}
}
2.依存関係をクラスに分ける
1のクラスではギア(Gear)に関するメソッドに車輪(Wheel)についての情報(rim,tire)までも含まれていた。これは単一責任の原則(SRP)の反するし、拡張性のために分離シておいたほうが良い。
import { Wheel } from "./Wheel";
class Gear {
constructor(private _chainring: number, private _cog: number, private wheel?: Wheel) {
}
get cog(): number {
return this._cog;
}
get chainring() {
return this._chainring;
}
public ratio(): number {
return this.chainring / this.cog
}
public gearInches() {
if (this.wheel) {
return this.ratio() * this.wheel.diameter();
}
return null;
}
}
export class Wheel {
private PI = 3.14;
constructor(private _rim: number, private _tire: number) {
}
get rim() {
return this._rim;
}
get tire() {
return this._tire;
}
diameter() {
return this.rim + this.tire * 2;
}
cicle() {
return this.diameter() * this.PI;
}
}
3.引数をハッシュにする
上記までは引数の順番を知らなくては正しくクラスを使えなかった。そのため、引数としてわかりやすくパラメータを与えることにする。
import { Wheel } from "./Wheel";
export class Gear {
private readonly _chainring:number;
private readonly _cog: number;
private readonly wheel?: Wheel;
constructor(args: any) {
this._chainring = args['chainring']
this._cog = args['cog']
this.wheel = args['wheel']
}
get cog(): number {
return this._cog;
}
get chainring() {
return this._chainring;
}
public ratio(): number {
return this.chainring / this.cog
}
public gearInches() {
if (this.wheel) {
return this.ratio() * this.wheel.diameter();
}
return null;
}
}
このクラスの使い方はこう
const args = {
chainring: 10,
cog:10,
wheel: new Wheel(10,10)
}
const gear = new Gear(args);
console.log(gear.gearInches()) // => 30
3.Factoryクラス
外部のクラスなど自分でいじれない場合、引数の順番を変えたりハッシュ(JSON形式)にできないので、Factoryクラスでラップすることで解決する。
import { Wheel } from "./Wheel";
class GearFactory {
constructor(private args:any) {
}
gear(): Gear{
return new Gear(this.args['chainring'],this.args['cog'],this.args['wheel'])
}
}
export class Gear {
constructor(private _chainring: number, private _cog: number, private wheel?: Wheel) {
}
get cog(): number {
return this._cog;
}
get chainring() {
return this._chainring;
}
public ratio(): number {
return this.chainring / this.cog
}
public gearInches() {
if (this.wheel) {
return this.ratio() * this.wheel.diameter();
}
return null;
}
}
const args = {
chainring: 10,
cog:10,
wheel: new Wheel(10,10)
}
const gear = new GearFactory(args).gear();
console.log(gear.gearInches()); //=> 30
いまのところ以上!!
まだ導入なのでオブジェクト指向というよりリファクタリングっぽいが、今後オブジェクト指向実践になるのだろうか!!!
Author And Source
この問題について(TypeScriptでオブジェクト指向実践 その①), 我々は、より多くの情報をここで見つけました https://qiita.com/satons/items/61a52e34080c7503b810著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .