2016-06-13 2 views
2

私はこのクラスを持っている:ベースタイプのみに基づいて派生オブジェクトを作成する方法は?例えば

public abstract class Device 
{ 
    public Device() 
    { 
    } 

    public Device(XmlDevice xmlDevice) 
    { 
     // creating device by xmlDevice 
    } 
} 

public class Modem : Device 
{ 
    public Modem() 
    { 
    } 

    public Modem(XmlModem modem) 
    { 
     // creating modem by xmlModem 
    } 
} 

public class Plc : Device 
{ 
    public Plc() 
    { 
    } 

    public Plc(XmlPlc plc) 
    { 
     // creating plc by xmlPlc 
    } 
} 


public abstract class XmlDevice 
{ 
    public XmlDevice() 
    { 
    } 
} 

public class XmlModem : XmlDevice 
{ 
    public XmlModem() 
    { 
    } 
} 

public class XmlPlc : XmlDevice 
{ 
    public XmlPlc() 
    { 
    } 
} 

私はXmlDeviceオブジェクトのリストを持っている - どのように私はそのタイプに基づいてデバイスオブジェクトを作成することができますか?私はこのようにすることができます:

foreach(xmlDevice in xmlDevicesList) 
{ 
    if(xmlDevice is XmlModem) 
     devicesList.Add(new Modem((XmlModem)xmlDevice)); 
    else if(xmlDevice is XmlPlc) 
     devicesList.Add(new Plc((XmlPlc)xmlDevice)); 
} 

しかし、私は "is"ステートメントとキャストオブジェクトを避けたいと思います。これはもっとクリーンな方法ですか?

+2

ファクトリデザインパターン –

+0

を参照してください。しかし、工場では "is"とキャストも使用する必要があります...? – Bero

+0

私は数年前に尋ねた同様の質問に対する回答を見てください:http://stackoverflow.com/questions/15998071/getting-past-open-closed-principle –

答えて

4

あなたの現在の実装に対するあなたの嫌悪感は十分に確立されています。私はあなたが新しいデバイスタイプを追加するとすぐに中断することを約束できます。さらに悪いことに、コンパイラは、インスタンス型チェックが網羅的であることを意図していることを知る方法がないため、エラーを知らせることによってあなたを助けません。あなたがXml*クラスを変更することができる場合

、あなたは単に派生クラスでCreateDeviceXmlDeviceで抽象メソッドを導入し、それをオーバーライドすることができます:

devicesList = xmlDevicesList.ConvertAll(x => x.CreateDevice()); 

public abstract class XmlDevice 
{ 
    // ... 
    public abstract Device CreateDevice(); 
    // ... 
} 

public class XmlModem : XmlDevice 
{ 
    // ... 
    public override Device CreateDevice() 
    { 
     return new Modem(this); 
    } 
    // ... 
} 

は今、あなたは、単にこれを行うことができます

おそらく、この方法の最大の利点は、CreateDeviceメソッドを実装せずにコンパイラが新しいデバイスタイプを作成することを免れないことです。

+0

ありがとう、これはとても単純です...コンストラクタにいくつかの異なるパラメータ(モデムとPLCでは違いがあります)を渡したい場合は、工場が必要でしょうか? – Bero

+0

どのようなパラメータがありますか? –

+0

その他のオブジェクト。例:Antena for ModemおよびOutputModule for Plc – Bero

関連する問題