2012-01-14 10 views
8

現在、私は簡単なテストプロジェクトでトランザクションスクリプトパターン(正確にはを使用して、マーティンファウラーdescribed)を実装しようとしています。 ICommandインターフェースから継承された具象クラスで実行された指定されたメソッドが実行されたときにどのように結果を得るかを知っている。コマンドパターンで実行されたメソッドの結果を取得

私の持つ機能を明確にするためのコードを示しましょう。 私はICommandのインタフェース

public class CalculateSalaryCommand : ICommand 
{ 
    private readonly CalculateSalaryTS _salaryTs; 
    private readonly int _hour; 
    private readonly int _salaryPerHour; 

    public CalculateSalaryCommand(CalculateSalaryTS salaryTs, int hour, int salaryPerHour) 
    { 
     _salaryTs = salaryTs; 
     _hour = hour; 
     _salaryPerHour = salaryPerHour; 
    } 

    public void Execute() 
    { 
     _salaryTs.CalculateSalary(_hour, _salaryPerHour); 
    } 
} 

、あなたは私が、その後、具体的なコマンドクラスのインスタンスを渡す見ることができるようにCalculateSalaryTS

public class CalculateSalaryTS { 
    public void CalculateSalary(int _hour, int _salaryPerHour) { 
     Result = _hour * _salaryPerHour; 
    } 
} 

という名前のシンプルなトランザクションスクリプトのクラスから継承したシンプルなCalculateSalaryCommandクラスをしましたExecuteメソッドの内部で、そのインスタンスから操作を実行します。まあ、すべてがうまく見えます。しかし、私は整数でなければならない実行されたメソッドの結果を返すことができないという問題があります。

その後
public interface ITransactionResult<TResult> 
{ 
    TResult Result { get; set; } 
} 

CalculateSalaryTSクラスは次のようになりました: この問題を処理するために、私は次のようになり、各トランザクションは、一般的なITransactionResultインタフェースから継承する必要があるトランザクションスクリプト層にいくつかのコードを追加することを決定しました

public class CalculateSalaryTS : ITransactionResult<Int32> { 

    public void CalculateSalary(int _hour, int _salaryPerHour) { 
     Result = _hour * _salaryPerHour; 
    } 

    public int Result { get; set; } 

} 

用途:

var script = new CalculateSalaryTS(); 
    var command = new CalculateSalaryCommand(script, 10, 20);   
    command.Execute(); 
    Console.WriteLine("Salary is {0}", script.Result); 

私はこの方法に独自の制限があることを知っていますが、この状況を処理する別のアイデアをあなたに提供するまでは選択肢がありません。

ありがとうございます。

答えて

18

ので、:

public interface ICommandWithResult<T> : ICommand 
{ 
    T Result { get; } 
} 

public class CalculateSalaryCommand : ICommandWithResult<int> 
{ 
    public int Result { get; private set; } 

    // ... 

    public void Execute() 
    { 
    _salaryTs.CalculateSalary(_hour, _salaryPerHour); 
    this.Result = _salaryTs.Result; 
    } 
} 

// Usage: 

var command = new CalculateSalaryCommand(new CalculateSalaryTS(), 10, 20); 
command.Execute(); 
Console.WriteLine("Salary is {0}", command.Result); 
+0

デニスの返信ありがとうございます。あなたはすばらしい解決策を好みました。しかし、私はパターンのコンセプトを設計するのが初めてであるため、ICommandの動作に追加機能を追加することについて混乱します。それが正しいか? – saber

+2

私は、必要に応じてコマンドを拡張することに問題があるとは思わない。デザインパターンとは、特定の問題や繰り返し発生する問題を解決する方法のガイダンスを意味します。彼らは石ではなく、あなたが建てることのできる土台になっています。あなたの特定のケースでは、インターフェイス 'ICommandWithResult 'を追加する必要はありません。 'ICommand'に' Result'プロパティを 'CalculateSalaryClass'に追加するだけでよいのです。 –

+0

+1ありがとうございます。 – saber

4

あなたは結果を返すことができるコマンドパターンを探していると思います。あなたは絶対にコマンド実行直後に結果を取得する必要がある場合は、コマンドオブジェクトに結果格納することができ

interface ICommand<TResult> 
    { 
     TResult Execute(); 
    } 


public class CalculateSalaryCommand : ICommand<int> 
{ 
    private readonly CalculateSalaryTS _salaryTs; 
    private readonly int _hour; 
    private readonly int _salaryPerHour; 

    public CalculateSalaryCommand(CalculateSalaryTS salaryTs, int hour, int salaryPerHour) 
    { 
     _salaryTs = salaryTs; 
     _hour = hour; 
     _salaryPerHour = salaryPerHour; 
    } 

    public int Execute() 
    { 
     return _salaryTs.CalculateSalary(_hour, _salaryPerHour); 
    } 
} 
+2

コマンドパターンのメソッドがvoidでなければなりませんが、してみましょうあなたが正しいことを想像してください。もし無効な方法を実行したいのであればどうですか?私は何をすべきか ? – saber

+0

@SaberAmani:2つの方法で、nullを返すICommand を実装するか、 'GetResult()'と呼ばれるメソッド/プロパティを実装します。 – Spoike

関連する問題