0

これは、例でよりよく説明されています。現在、私は次のようなものを持っています:

public class Car {
    internal string SaleCode {get; set;} //Spring, Summer, ...
    public string Name {get; set; }  //Model name
}

public interface ICarFactory 
{
    Car GetSummerSaleCar();
    Car GetSpringSaleCar();
}

public class FordFactory : ICarFactory 
{
    public Car GetSummerSaleCar() {
        return new Car() {Name="Fiesta"};
    }
    public Car GetSpringSaleCar() {
        return new Car() {Name="Fusion"};
    }
}

public class CarProvider {
    public void ProduceCars(ICarFactory factory) {
        var inventory = new List<Car>();
        Car car = null;
        car = factory.GetSummerSaleCar();
        car.SaleCode = "SMR";
        inventory.Add(car);

        car = factory.GetSpringSaleCar();
        car.SaleCode = "SPG";
        inventory.Add(car);
    }
}

車の SaleCode は各メソッドで常に同じでなければならないため、CarFactory の実装ではこの値を設定しないでください。現在、これを CarProvider クラスに設定していますが、これをインターフェイスから取得する方法があるかどうかを知りたいです。私が考えることができる唯一のことは、型を設定できるインターフェイス内のメソッド定義に適用される属性を使用することですが、別の代替手段が必要だと感じています。

アイデア?

アップデート

ご参考までに、インターフェイスの各メソッドに属性を追加することについて言及したとき、これについて話していました。

public class SaleAttribute : Attribute
{
    public string Code { get; set; }
}


public interface ICarFactory
{
    [Sale(Code = "SMR")]
    Car GetSummerSaleCar();
    [Sale(Code = "SPG")]
    Car GetSpringSaleCar();
}

public void ProduceCars(ICarFactory factory)
{
    var inventory = new List<Car>();
    foreach (var method in typeof(ICarFactory).GetMethods())
    {
        String carType = null;
        var attributes = method.GetCustomAttributes(typeof(SaleAttribute), false);
        if (attributes.Length == 1)
        {
            saleCode = ((SaleAttribute)attributes[0]).Name;
            Car car = (Car)method.Invoke(factory, null);
            car.SaleCode = saleCode;
            inventory.Add(car);
        }
    }
}

これには、インターフェイスにメソッドが追加された場合に CarProvider を変更する必要がないという追加の利点があります。不利な点は、Reflection に関連するオーバーヘッド (パフォーマンスとメンテナンス) です。

更新2

私の状況をよりよく反映するように、例を車の種類から販売コードに変更しました。

4

2 に答える 2

3

Mike 最良のアプローチは、抽象型の Car と 2 つの派生クラス (CompactCar と MediumCar) を持つことだと思います。

public abstract class Car { 
    internal string Type {get; protected set;} //Compact, Medium, Large, ... 
    public string Name {get; set; }  //Model name 
} 

public class CompactCar : Car
{
     public CompactCar() { this.Type = "Compact"; }
}

public class MediumCar : Car
{
     public MediumCar() { this.Type = "Compact"; }
}

したがって、次のような特定のタイプを返すことができます。

public interface ICarFactory      
{     
    CompactCar GetCompact();     
    MediumCar GetMedium();     
}  
public class FordFactory : ICarFactory    
{   
    public CompactCar GetCompact() {   
        return new CompactCar() {Name="Fiesta"};   
    }   
    public MediumCar GetMedium() {   
        return new MediumCar() {Name="Fusion"};   
    }   
}  

抽象型 Car で車を参照できるため、これを使用するソース コードへの影響は最小限です。

于 2012-05-04T19:22:11.453 に答える
0

CarType.Create(Medium)代わりにどうnew Carですか?

私はという工場を提案していますCarType

public class CarType{
   public class CarType(instName){
      this.instName = instName;
   }
   public Car Create(){
      return new Car(){Type=instName;}
      //or alternatively, if you have more implementations for the cars
      //return (Car)Activator.CreateInstance(this.instName);
   }
   public static CarType Compact = new CarType("Compact");
   public static CarType Medium = new CarType("Medium");
}

使用法は

Medium.Create(){Name="Fiesta";}

しかし、それはまだCarFactorysメソッド内にあるので、あまり役に立ちません...

于 2012-05-04T19:11:49.953 に答える