2013-03-24 14 views
6

Tôi hiện đang nghiên cứu các mẫu thiết kế và hiện tôi đang xem mẫu lệnh.Trong C# làm cách nào để triển khai đúng Mẫu Thiết kế Lệnh?

Đây là mã hiện tại của tôi:

// 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(); 
    } 
} 

Chú ý rằng trong phương pháp chính của tôi, tôi có thể truy cập vào các phương pháp SetAction của người nhận có khả năng thiết lập mà lệnh để sử dụng.

Câu hỏi của tôi là: việc triển khai của tôi có vi phạm mục đích của mẫu lệnh và việc triển khai của tôi sai do tôi có thể truy cập vào mã khách hàng của mình không? Nếu có, làm thế nào tôi có thể cải thiện việc triển khai này.

+0

Tại sao rigamarole với CommandOptions enum và phương thức Calculator.GetResult() phức tạp? –

+1

Bạn có thể thấy liên kết này hữu ích, cả cho mẫu Lệnh và cho các mẫu thiết kế khác mà bạn đã làm việc thông qua: http://www.dofactory.com/Patterns/PatternCommand.aspx. –

+1

Tôi khuyến khích bạn đọc những bài viết này ... [.NET Junkie Command Architecture] (http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=91) và [.NET Junkie Query Kiến trúc] (http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=92) – TylerOhlsen

Trả lời

7

Tôi chụp một đoạn chỉnh sửa văn bản (tức là chưa chạy, mong đợi lỗi cú pháp :)) mã của bạn. Đây là cách tôi sẽ mô hình hóa vấn đề của bạn.

Một số điểm-

1) Yêu cầu thực hiện tác vụ. Trong trường hợp của bạn, bạn có các lớp lệnh, nhưng máy tính của bạn giữ logic để tính toán. Thay vào đó, đóng gói hành động lệnh trong chính lớp lệnh

2) Tôi đã đặt một nhà máy để ánh xạ tùy chọn lệnh tới lệnh và lưu một vài dòng bằng cách xóa break s vì tôi có thể trả về lệnh.

3) Bộ tiếp nhận IRI hiện giữ các giá trị được chuyển tới Command. Trong trường hợp này, vì các toán tử của chúng ta đều là nhị phân, tôi vừa mới sử dụng X và Y. Có thể là một mảng hoặc bất kỳ loại phức tạp nào khác cho các trường hợp khác.

4) Không cần thiết, trừ khi bạn thực sự muốn.

Chỉnh sửa Khi nhìn lại, tôi nghĩ một giải pháp tốt hơn sẽ không đăng ký người nhận bằng lệnh, thay vì truyền các tham số trong khi gọi lệnh.

//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(); 
    } 
}