2013-03-24 16 views
6

Şu anda tasarım desenleri çalışıyorum ve şu anda komut desenine bakıyorum. benim ana yöntemde, ben kullanmak komuta ayar yeteneğine sahiptir alıcısının SetAction yöntemini erişebilmesiC# Komut Tasarım Kalıbını düzgün bir şekilde nasıl uygularım?

// this is the receiver 
class Calculator : IReceiver 
{ 
    int x; 
    int y; 

    CommandOptions command; 

    public Calculator(int x, int y) 
    { 
     this.x = x; 
     this.y = y; 
    } 

    public void SetAction(CommandOptions command) 
    { 
     this.command = command; 
    } 

    public int GetResult() 
    { 
     int result = 0; 

     switch(this.command) 
     { 
      case CommandOptions.ADD: 
       result = this.x + this.y; 
       break; 

      case CommandOptions.SUBTRACT: 
       result = this.x - this.y; 
       break; 

      case CommandOptions.MULTIPLY: 
       result = this.x * this.y; 
       break; 
     } 

     return result; 
    } 
} 

// command 
abstract class Command 
{ 
    protected IReceiver receiver; 

    public Command(IReceiver receiver) 
    { 
     this.receiver = receiver; 
    } 

    public abstract int Execute(); 
} 

class AddCommand : Command 
{ 
    public AddCommand(IReceiver receiver) : base(receiver) 
    { 
    } 

    public override int Execute() 
    { 
     reciever.SetAction(CommandOptions.ADD); 
     return receiver.GetResult(); 
    } 
} 

enum CommandOptions 
{ 
    ADD, 
    SUBTRACT, 
    MULTIPLY 
} 

interface IReceiver 
{ 
    void SetAction(CommandOptions command); 
    int GetResult(); 
} 


class Program 
{ 
    static void Main(string[] args) 
    { 
     IReceiver receiver = new Calculator(500, 25); 

     //#Issue:The SetAction() method of the receiver is accessible. 
     //receiver.SetAction(CommandOptions.ADD); 
     receiver.SetAction(CommandOptions.MULTIPLY); 
     Command command = null; 

     Console.Write("Enter option 1-3: "); 

     int commandOption = int.Parse(Console.ReadLine()); 

     switch(commandOption) 
     { 
      case 1: 
       command = new AddCommand(receiver); 
       break; 

      case 2: 
       command = new SubtractCommand(receiver); 
       break; 

      case 3: 
       command = new MultiplyCommand(receiver); 
       break; 

      default: 
       command = new AddCommand(receiver); 
       break; 
     } 

     Console.WriteLine(command.Execute()); 
     Console.ReadKey(); 
    } 
} 

Uyarı:

İşte benim şimdiki kodudur.

Soruma sorum: uygulamam komut modelinin amacını ihlal ediyor mu? Uygulamam yanlış mı çünkü istemci koduma erişebiliyorum? Eğer öyleyse, bu uygulamayı nasıl geliştirebilirim.

+0

Neden enum CommandOptions ve karmaşık Calculator.GetResult() metodu ile rigamarole? –

+1

Bu bağlantıyı hem Komut düzeni hem de üzerinde çalıştığınız diğer tasarım desenleri için yararlı bulabilirsiniz: http://www.dofactory.com/Patterns/PatternCommand.aspx. –

+1

Bu makaleleri okumanızı öneririm ... [.NET Junkie Komutu Mimarisi] (http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=91) ve [.NET Junkie Query Mimari] (http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=92) – TylerOhlsen

cevap

7

Kodunuzu kullanarak bir metin düzenleme (yani, onu çalıştırmadım, sözdizimi hataları bekliyoruz) aldım. İşte problemini nasıl modelleyebilirim.

Bazı points-

1) Var komut

eylem yapmak. Durumunuzda, komut sınıflarınız var, ancak hesap makinesi hesaplama için mantığı tutuyor. Bunun yerine, komut sınıfının içinde komut eylemini kendi içinde kapsüllemek

2) Komut seçeneğini komutla eşleştirmek için bir fabrika yerleştirdim ve komutu geri alabildiğim için break s'yi kaldırarak birkaç satır kaydettim.

3) IReceiver şimdi Komuta iletilen değerleri tutar. Bu durumda, tüm operatörlerimiz ikili olduğundan, sadece X ve Y kullanıyorum. Diğer durumlar için bir dizi veya başka bir karmaşık tip olabilir.

4) Kesinlikle istemediğiniz sürece, enum gerekli değildir.

Düzen On yeniden görünümlü ben daha iyi bir çözüm yerine, komutlarla alıcıyı kayıt komutunu başlatırken parametreleri üzerinde geçemez etmek olacağını düşünüyorum.

//this is the receiver 
class Calculator : IReceiver 
{ 
    int y; 
    int x; 

    public Calculator(int x, int y) 
    { 
     this.x = x; 
     this.y = y; 
    } 

    public int Calculate(int commandOption) 
    { 
     Command command = new CommandFactory().GetCommand(commandOption); 
     return command.Execute(x , y); 
    } 

} 


//command 
interface ICommand 
{  
    int Execute(int x, int y); 
} 

class AddCommand : Command 
{ 
    public override int Execute(int x, int y) 
    { 
     return x + y; 
    } 
} 

class MultiplyCommand : Command 
{ 
    public override int Execute(int x, int y) 
    { 
     return x * y; 
    } 
} 

class SubtractCommand : Command 
{ 
    public override int Execute(int x, int y) 
    { 
     return x - y; 
    } 
} 

interface IReceiver 
{ 
    int X {get; set;} 
    int Y {get; set;} 
    int Calculate(int commandOption); 
} 

public class CommandFactory 
{ 
    public GetCommand(int commandOption) 
    { 
     switch(commandOption) 
     { 
      case 1: 
       return new AddCommand(); 
      case 2: 
       return new SubtractCommand(); 
      case 3: 
       return new MultiplyCommand(); 
      default: 
       return new AddCommand(); 
     }  
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     IReceiver receiver = new Calculator(500, 25); 
     //#Issue:The SetAction() method of the receiver is accessible. 
     //receiver.SetAction(CommandOptions.ADD); 

     //Receiver no longer exposes SetAction 
     //receiver.SetAction(CommandOptions.MULTIPLY); 
     Console.Write("Enter option 1-3: "); 
     int commandOption = int.Parse(Console.ReadLine()); 

     Console.WriteLine(receiver.Calculate(commandOption)); 
     Console.ReadKey(); 
    } 
} 
İlgili konular