2016-12-22 13 views
0

TypeScriptでいくつかのES6クラスを使用してユーザーインターフェイスを構築しています。私はControlと呼ばれる基本クラスを持っています。いくつかのプロパティが既に設定されているControlのインスタンスであるButtonを作成する方法が必要です。私はControlのサブクラスとしてButtonを実装しました。TypeScript OOデザイン - コンストラクタのみが異なる場合にサブクラスを使用する

私のサブクラスで発生する唯一のことは、コントロールのtypeを 'button'に設定してsuper()を呼び出すことです。また、Buttonでは、特定のコントロールプロパティが必須になります。それは間違っていると感じる。私は本当にサブクラスを使用すべきですか?これを行うための良いOOPの方法は何でしょうか?

interface ControlOptions { 
    type: string; 
    label?: string; 
    onClick?:() => void; // optional here 
    submit?: boolean; 
    transition?: Transition 
} 

class Control { 
    constructor(options: ControlOptions) { 

    } 

    // Some methods left out for brevity. 
} 


interface ButtonOptions { 
    label: string 
    onClick:() => any // mandatory here 
    submit?: boolean 
    transition?: Transition 
} 

// should this be a subclass? 
class Button extends Control { 
    constructor(options: ButtonOptions) { 
    let controlProps = { type: 'button', ...options }; 

    super(controlProps); 

    if (options.transition) { 
     options.transition.setSource(this); 
    } 
    } 
} 
+0

ので、二つのクラス間の*だけ*変更は 'タイプです。「button''? – thedayturns

+0

ほとんどの場合、ButtonのonClickオプションは必須ですが、Controlではオプションです – chazmuzz

答えて

0

私にはよく似ています。サブクラスがわずかな変更しか持たないからといって、それが必要でないか間違っているというわけではありません。私は非常に小さいクラスやほとんど何もしないクラスを作成することがよくあります。また

、基底クラスはを可能にするので、基底クラスは、値または未定義を期待ので、ちょうどそれに値を渡すためにOKですサブクラスは、それに渡される特定のデータは必須である適用を有することは、この場合に完全に問題ありサブクラスから。一方、基本クラスに値を期待して、それをサブクラスでオプションにすることは、間違ってコンパイルエラーになることになります。

でも、私は簡潔にするため、これらの変更をお勧めします:

interface ControlOptions { 
    label?: string; 
    onClick?:() => void; 
    submit?: boolean; 
    transition?: Transition; 
} 

class Control { 
    constructor(type: string, options: ControlOptions = {}) { 
    } 
} 

interface ButtonOptions extends ControlOptions { 
    onClick:() => void; // make mandatory 
} 

class Button extends Control { 
    constructor(options: ButtonOptions) { 
    super('button', options); 

    if (options.transition) { 
     options.transition.setSource(this); 
    } 
    } 
} 

または代わりに:

class Control { 
    constructor(options: { type: string; } & ControlOptions) { 
    } 
} 

class Button extends Control { 
    constructor(options: ButtonOptions) { 
    super({ type: 'button', ...options }); 
    // etc... 
    } 
} 
関連する問題