2016-09-07 7 views
1

軽量/重い車のインスタンスと、北極軽量/重い車のインスタンスが必要です。 ArcticCarコードのコードをArcticLight/HeavyCarに複製しないための継承(または合成)の正しい方法は何ですか?右継承命令

class Car { 
    startEnging() { 
     turnOnPeripheralDevices(); 
     checkFuelLevel(); 
     // + other default actions. Some of them can be overrided in child classes to add specific actions 
     log("engine started"); 
    } 
    /* Common car stuff */ 
} 

class LightCar extend Car { 
    override startEngine() { 
     log("light car prepare to start"); 
     parent.startEnging(); 
    } 
    /* Basic light car stuff */ 
} 
class HeavyCar extend Car { 
    override startEngine() { 
     turnOnLights(); 
     log("heavy car prepare to start"); 
     parent.startEnging(); 
    } 
    override turnOnPeripheralDevices() { 
     parent.turnOnPeripheralDevices(); //Car's default actions 
     // additional actions for HeavyCars only 
    } 
    /* Basic heavy car stuff */ 
} 

class ArcticCar extend Car { 
    override startEngine() { 
     warmUpEngine() 
     wait10seconds(); 
     log("arctic mode: warming up engine"); 
     parent.startEnging(); 
    } 
    /* A lot of common stuff for arctic cars. Can overwrite some common Car's functions */ 
} 

class LightArcticCar extend **LightCar, ArcticCar** { 
    override startEngine() { 
     log("arctic ligh car prepare to start"); 
     parent.startEnging(); 
    } 
    /* Arctic light car stuff. Can overwrite some specific LightCar's functions */ 
} 
class HeavyArcticCar extend **HeavyCar, ArcticCar** { 
    override startEngine() { 
     if(checkForecast()) 
      parent.startEnging(); 
    } 
    override turnOnPeripheralDevices() { 
     parent.turnOnPeripheralDevices(); //Car's + HeavyCar's default actions 
     // additional actions of HeavyArctic car 
    } 
    /* Arctic heavy car stuff. Can overwrite some specific HeavyCar's functions */ 
} 

class Main { 
    buggy = new LightCar(); 
    awdSUV = new HeavyCar(); 

    snowmobile = new ArcticLightCar(); 
    mobileLaboratory = new ArcticHeavyCar(); 
} 
+5

あなたが明示的にどのようにオンにするかどうかを知っているだろう、 'HeavyArcticCar'にそう言う場合を除き継承 – sidgate

+5

以上の賛成の構成は、Decoratorパターンhttps://en.wikipedia.org/wiki/Decorator_pattern – lhoworko

+0

のための良い場所であることかもしれませんエンジンを暖める前または後に点灯しますか? – Andreas

答えて

0

私の意見では、このデザインにアプローチする最善の方法は、問題のドメインを詳しく見ていくことです。私には、そこに1つ以上のエンティティ(車)があるように見えます。エンジン、カーライト、予報などがあります。 その場合は、より良いデザインは、モデル内の各エンティティのクラスを持っているだろう:

class Car { 
    protected Engine engine; 
    protected CarLights carLights; 
    void start() { 
     engine.start(); 
    } 
} 

class Engine { 
    void start() { ... } 
    void warmUp() { ... } 
} 

class CarLights { 
    void turnOn() { ... } 
} 

class Forecast { 
    void check() { ... } 
} 

階層は次のようになります。OOPの強力なポイントの

class LightCar extend Car { 
    // no code for start 

    /* Basic light car stuff */ 
} 

class HeavyCar extend Car{ 

    void start() { 
     carLights.turnOn(); 
     log("heavy car prepare to start"); 
     parent.start(); 
    } 

    /* Basic heavy car stuff */ 
} 

class ArcticCar extend Car { 
    void startEngine() { 
     engine.warmUp() 
     wait10seconds(); 
     log("arctic mode: warming up engine"); 
     parent.start(); 
    } 
    /* A lot of common stuff for arctic cars. 
     Can overwrite some common Car's functions */ 
} 

class HeavyArcticCar extend ArcticCar { 
    Forecast f; // if it a component of a car. If not, then it should be a local variable in start() 
    void start() { 

     if(f.check()) 
      parent.startEnging(); 
    } 
} 

一つでありますそれはすぐに問題に近いコードでソリューションをモデル化することができます。

たとえば、この場合の構成は、はるかに自然なので、車の実際の構成要素を厳密に反映します。コードはウォームアップと

CarLightsを開始する - - コードをオンにする/オフライト

エンジン:

https://en.wikipedia.org/wiki/Single_responsibility_principle

だからここに責任がある:

Plusは、このあり

予測コードを確認する

車と派生品 - 上記の3つをすべてまとめ、その機能を使用します。

最後に、Engine、CarLights、Forecastを共通のインターフェイス(CarComponentなど)に実装することで、設計をさらに改善することができます。これらは共通であり、すべての車のコンポーネントであり、CarComponent車のクラスで。コンポーネントをより簡単に追加または削除できるので、これはさらに柔軟になります。

+0

同じ問題:HeavyArcticCar.start()はライトをオンにしません(すべてのヘビーカーのデフォルト動作)。 turnLightOn()に加えて、ヘビーカーには他のデフォルトのアクションがいくつかあります。 HeavySandCar - > SandCarとその他の車のクラスとグループがあります:( – Maxx

+0

HeavyArcticCar.start()メソッドのcarLightsインスタンスでturnOnメソッドを明示的に呼び出すことができます。 一方、複数のカテゴリを扱いたいだけでなく、継承を使って100%のコードを再利用したい場合(あるいは、あなたの質問のように右の継承順序)、答えは簡単です。言語ではできません単一の継承を持つ。複数の継承を持つ言語であっても、面倒なデザインが得られます。 –

+0

トピックのコードを更新しました。恐らく問題を見やすくなります:) HeavyCarとArcticCarは同じ時間にあります:ArcticCarは車でHeavyCarは車です – Maxx