2010-08-10 33 views
16

Dưới đây là những gì tôi có cho đến nay:Cách sử dụng Mẫu Chiến lược với C#?

namespace Strategy 
{ 
    interface IWeaponBehavior 
    { 
     void UseWeapon(); 
    } 
} 

namespace Strategy 
{ 
    class Knife : IWeaponBehavior 
    { 
     public void UseWeapon() 
     { 
      Console.WriteLine("You used the knife to slash the enemy! SLASH SLASH!"); 
     } 
    } 
} 

namespace Strategy 
{ 
    class Pan : IWeaponBehavior 
    { 
     public void UseWeapon() 
     { 
      Console.WriteLine("You use the pan! 100% Adamantium power! BONG!"); 
     } 
    } 
} 

Bây giờ nếu tôi có một lớp cha Character.cs. làm thế nào mà siêu lớp đó có thể thực hiện vũ khí để các lớp trẻ em có thể cụ thể hơn.

namespace Strategy 
{ 
    class Character 
    { 
     public IWeaponBehavior weapon; 

     public Character(IWeaponBehavior specificWeapon) 
     { 
      weapon = specificWeapon; 
     }   
    } 
} 

namespace Strategy 
{ 
    class Thief : Character 
    { 

    } 
} 

Làm cách nào để triển khai tính năng này? Tôi rất bối rối về những gì mã thực sự cần phải được.

Tôi biết điều này có thể đòi hỏi quá nhiều, nhưng nếu bạn có thể viết mã thực tế để tôi có thể nghiên cứu nó, điều đó sẽ rất tốt đẹp cho các bạn. Tôi học bằng cách nhìn thấy mã. : P Nhiều người có thể hưởng lợi từ câu hỏi này.

+9

"SLASH SLASH!" quy tắc một phần :) – thelost

+1

Tùy thuộc vào đặc tính khác của 'Ký tự' bạn có thể loại bỏ các lớp kế thừa và sử dụng một nhà máy có thể thiết lập các đặc tính và chiến lược cần thiết. –

Trả lời

26

sử dụng trong lớp Character?

public class Character 
{ 
    public Character(IWeaponBehavior weapon) 
    { 
     this.weapon = weapon; 
    } 

    public void Attack() 
    { 
     weapon.UseWeapon(); 
    } 

    IWeaponBehavior weapon; 
} 

public class Princess: Character 
{ 
    public Princess() : base(new Pan()) { } 
} 

public class Thief: Character 
{ 
    public Thief() : base(new Knife()) { } 
} 

... 

Princess p = new Princess(); 
Thief t = new Thief(); 

p.Attack(); // pan 
t.Attack(); // knife 

Chỉnh sửa theo yêu cầu.

+0

hmm tôi thích của bạn tốt hơn tôi nghĩ. –

+0

mặc dù hmm, ý định có thể rõ ràng về mặt ngữ nghĩa trong mỏ. –

+3

@Joshua - Nhưng bạn giả sử tất cả các công chúa sẽ sử dụng một chiếc Pan, nếu bạn có một công chúa ác người thích sử dụng một con dao ... – SwDevMan81

5

Có một vài khả năng. Những gì bạn đang thực sự yêu cầu là, "làm thế nào một nhân vật cụ thể nên biết vũ khí để sử dụng?".

Bạn có thể có một nhà máy nhân vật để tạo và tiêm đúng loại vũ khí vào nhân vật (Nghe sai :)), hoặc để cho nhà xây dựng của một nhân vật cụ thể chăm sóc tạo vũ khí.

+1

Ok, nhưng nó sẽ linh hoạt hơn nếu vũ khí của một nhân vật có thể được thay đổi bất cứ lúc nào. Có lẽ tên trộm đã đánh mất con dao của họ có thể lấy một cái chảo và ứng biến. Nói cách khác, không có vấn đề làm thế nào bạn khởi tạo nó, không có lý do để làm cho nó bất biến. –

+0

@Steven: bạn giả định rằng mức độ linh hoạt này là cần thiết: không có nhu cầu cụ thể để làm cho nó có thể thay đổi. Bạn nên làm điều đơn giản nhất đáp ứng các yêu cầu thực tế (bất kể chúng có thể là gì!). –

+0

@Dan: Từ những gì tôi hiểu về miền vấn đề, tính linh hoạt này có thể là một ý tưởng hay. Cuối cùng, đó là sự lựa chọn của Sergio; công việc của tôi là cung cấp nó. –

3
class Character 
    { 
    private IWeaponBehavior _weapon; 

    // Constructor 
    public Character(IWeaponBehavior strategy) 
    { 
     this._weapon = strategy; 
    } 

    public void WeaponInterface() 
    { 
     _weapon.UseWeapon(); 
    } 
    } 
+2

Hàm tạo của bạn cần phải là 'Ký tự' không phải là' Ngữ cảnh'. –

+0

Đã cập nhật cảm ơn. – SwDevMan81

+0

Lưu ý phụ: Nếu bạn đang sử dụng dấu gạch dưới hàng đầu để phân biệt các trường từ người dân địa phương, thì "điều này". là hoàn toàn dư thừa. –

1
 
public class Character 
{ 
    IWeaponBehavior Weapon; 
} 

public class Princess : Character 
{ 
    Weapon = new Pan(); 
} 

public class Thief : Character 
{ 
    Weapon = new Knife(); 
} 
+5

bạn nên gắn cờ mã của mình một cách rõ ràng là 'pseudo-code'! –

0

Nếu nhân vật của bạn đều có vũ khí đặc biệt của riêng mình, bạn không thực sự cần phải sử dụng mô hình chiến lược. Bạn có thể sử dụng đa hình đồng bằng. Nhưng mô hình chiến lược có thể sạch hơn.

Bạn chỉ cần intitialize vũ khí:

public class Character 
{ 
    IWeapenBehavior weapon; 

    public Attack() 
    { 
      weapon.UseWeapon(); 
    } 
} 


public class Thief : Character 
{ 
     Thief() 
     { 
      weapon = new Knife(); 
     } 
} 

Trong các mã điều khiển nhân vật của bạn, bạn có thể gọi phương thức Attack().

1

Hãy xem tiêm phụ thuộc & sau đó cũng xem xét Inversion of Control.

TekPub có một tập miễn phí tuyệt vời về hai ý tưởng này bằng cách sử dụng một mẫu rất giống với mẫu của bạn. Điều này sẽ giúp bạn với một mẫu cụ thể. :-)

http://tekpub.com/view/concepts/1

Mẫu mã từ video:

class Samurai { 
    IWeapon _weapon; 

    public Samurai() { 
    _weapon = new Sword(); 
    } 

    public Samurai(IWeapon weapon) { 
    _weapon = weapon; 
    } 

    public void Attack(string target) { 
    _weapon.Hit(target); 
    } 
} 

Trên đây là DI (với IWeapon constructor). Bây giờ thêm Inversion of Control bạn có thể kiểm soát nhiều hơn.

Sử dụng vùng chứa IOC, bạn sẽ có thể kiểm soát IWeapon thông qua việc phun thay vì trong chính lớp đó.

Video sử dụng NInject làm IOC và tạo điều khiển cho lớp và tất cả các lớp cần sử dụng IWeapon để sử dụng những gì bạn muốn ở một vị trí/khu vực cấu hình.

mẫu từ video:

class WarriorModule: NinjectModule { 
    public override void Load() { 
    Bind<IWarrior>().To<Samurai>(); 
    Bind<IWeapon>().To<Sword>(); 
} 

Cấu hình trên nói Ninject rằng bất cứ khi nào nó gặp một IWarrior sử dụng Samurai và bất cứ khi nào nó encourters một IWeapon sử dụng Sword.

Video tiếp tục giải thích cách thay đổi nhỏ này làm tăng tính linh hoạt của bạn. Nó bổ sung thêm một Module cho một Samuria sử dụng vũ khí tầm xa, v.v.

Bạn có thể thay đổi những thứ này nếu cần/muốn.

Các vấn đề liên quan