2010-06-17 36 views
6

Tôi có các lớp lệnh triển khai giao diện ICommand {Execute}. Một số lệnh có phần mã trùng lặp. Tôi có một vài lựa chọn như thế nào để làm khô:Lớp trình trợ giúp so với kế thừa chức năng. Thực hành tốt nhất

  • Tạo lớp helper tĩnh (es) và di chuyển mã trùng lặp có
  • Tạo lệnh thừa kế với các phương pháp helper được bảo vệ

Những gì bạn sẽ đề nghị và tại sao?

ADDED Cảm ơn mọi người đã trả lời, nhiều câu trả lời đều giống nhau và hữu ích!

Trả lời

3

Nó hoàn toàn phụ thuộc vào bản chất của mã trùng lặp của bạn.

Đầu vào/đầu ra của các chức năng trợ giúp của bạn là gì? Chúng có hoạt động trên một tập hợp các biến có liên quan một cách hợp lý không? Sau đó - vâng, bạn nên tạo một lớp cơ sở với các biến đó như các thành viên, và tập hợp các hàm trợ giúp có liên quan.

Nếu không, nếu các tham số trong các hàm trợ giúp của bạn không kết hợp, bạn sẽ triển khai các hàm đó dưới dạng hàm tĩnh, đúng không? Tôi không thấy lý do làm phức tạp những thứ với thừa kế trong trường hợp này và tôi sẽ làm điều đó chỉ với các hàm trợ giúp (hoặc, nếu ngôn ngữ của bạn không xử lý các hàm như là công dân lớp đầu tiên, hãy sử dụng lớp trợ giúp tĩnh).

3

Nếu có bất kỳ cơ hội nào mà logic trùng lặp có thể cần bởi các lớp khác ngoài cấu trúc phân cấp, tôi sẽ đặt nó vào các lớp trợ giúp tĩnh. Nếu không trong lớp cơ sở với kế thừa được bảo vệ.

2

Theo tôi, tôi sẽ đặt mã trùng lặp vào lớp cơ sở nếu nó chỉ liên quan đến phân cấp lớp đó và sẽ không được sử dụng bên ngoài phân cấp đó. Nếu có bất kỳ khả năng nào cho mã được sử dụng trên các lớp khác nhau thì hãy chuyển nó sang một lớp trợ giúp trong một dự án chung.

Tận hưởng!

5

Thay vì các lớp tĩnh, một tùy chọn khác là đặt mã chung vào một lớp mới và sử dụng tiêm phụ thuộc để chèn lớp trợ giúp vào các lệnh. Điều này cũng đi với các thành phần trên khái niệm thừa kế là tốt.

+0

Hoặc vòng khác: làm cho lớp trợ giúp một trình trang trí và đưa lớp lệnh vào lớp trợ giúp. – Ozan

+2

+1 Khi suy nghĩ về việc sử dụng lại mã, đừng nghĩ "thừa kế", hãy suy nghĩ "tập hợp". –

1

Có thể không có câu trả lời đúng/sai ở đây, mặc dù tôi cho rằng bạn chắc chắn có thể triển khai nó kém. Nó có thể rất phụ thuộc vào yêu cầu thực tế của bạn và làm thế nào liên quan đến lệnh của bạn là với nhau. Nói chung, tôi có thể đi với việc thực hiện lớp cơ sở và phân cấp thừa kế, giả sử rằng các lệnh có liên quan và mã liên quan trực tiếp đến các lệnh, không phải với một thực thể bên ngoài nào phải là một lớp theo đúng nghĩa của nó. Chắc chắn chúng có liên quan bởi thực tế là chúng là các lệnh và lớp cơ sở có thể phản ánh điều đó.

Nếu bạn có mã chỉ phổ biến với tập hợp con của các lệnh không liên quan và tạo phân cấp thừa kế sẽ buộc một mối quan hệ không tồn tại, sau đó thêm vào một lớp "trợ giúp" (không tĩnh, nếu có thể, để cải thiện khả năng kiểm thử) sẽ là một cách hoàn toàn tự nhiên để giải quyết vấn đề. Bạn có thể thấy rằng bạn có thể nhóm các phương thức "helper" một cách tự nhiên vào các lớp của riêng chúng. Ví dụ, nếu một số phương thức cần tương tác với hệ thống con xác thực của bạn, bạn có thể có một AuthenticationMediator cho các phương thức đó. Tôi cũng không thấy bất kỳ xung đột nào với việc thực hiện cả hai.

0

Nếu logic hoạt động trên giao diện thành viên, thay vì thực hiện triển khai thành viên, sau đó viết phương pháp trợ giúp [hoặc phương pháp khuyến nông].

public IRandom 
{ 
    byte NextByte(); 
} 

public static class IRandomExtensions 
{ 
    // logic that acts against public interface IRandom 
    // may be applied to all implementations 
    public static int GetNextUnbiasedInteger (this IRandom random) { } 
    public static IEnumerable<T> Shuffle<T> (
     this IRandom random, 
     IEnumerable<T> items) { } 
} 

Nếu logic kinh doanh hoạt động chống lại thực hiện thành viên,

public class SomeCommand : ICommand 
{ 
    // an implementation-specific member, NOT a member 
    // of ICommand 
    public int SomeControlCount { get; set; } 
} 

// a method that references implementation-speciic 
// details. where should this go? 
public void DoSomething() 
{ 
    SomeCommand command; 
    int count = command.SomeControlCount; 
} 

thì rất có thể chúng ta nên chặt chẽ hơn liên kết này để các lớp thực hiện. Nếu đây là một sự xuất hiện đủ phổ biến, thì một lớp cơ sở có thể có ý nghĩa.

Cá nhân, các hệ thống phân cấp phức tạp gặp nhiều rắc rối hơn chúng đáng giá, sử dụng phán đoán của riêng bạn về khả năng bảo trì, mức độ dễ đọc và sử dụng lại, và bạn nên ổn!

Hy vọng điều này sẽ hữu ích! :)

0

Người trợ giúp sử dụng mã không quốc tịch.

Mã phụ thuộc của nhà nước với nhiều phương pháp sử dụng kế thừa. Ví dụ: khi nhiều phương thức sử dụng biến thành viên được chia sẻ và do đó duy trì trạng thái được chia sẻ.

Mục tiêu là giảm số lượng mã trùng lặp và tùy thuộc vào loại mã đó. Tuy nhiên tôi thực sự ghét khi mọi người lạm dụng điều này và tạo ra các lớp siêu trừu tượng hoặc các hàm trợ giúp mà 7 nhảy tới mã trừu tượng khác, được đặt tên giống như "Executor" "Invoker" "DataConveyer" "DataManager" "SharedCode". Và bằng cách nào đó vào cuối tất cả những bước nhảy này thực sự đã xoay xở để thực hiện công việc mà nó được cho là, nhưng lại được kết nối với nhau mà bạn không chắc chắn nơi để thực hiện các thay đổi mới để thêm tính năng mới này. Tôi có nên làm điều đó DataConveyer hoặc tôi nên làm điều đó trong DataManager?

Vì vậy, mục tiêu vàng nên được, giữ cho nó đơn giản.

1

Việc sử dụng người trợ giúp bên trong mã của riêng bạn là một thực tiễn không tốt đến từ sự lười biếng.

Là người duy nhất có thể tình bạn thực sự cần giúp đỡ - là mở rộng các hành vi của các lớp niêm phong từ thư viện của bên thứ 3 như selen, vv

helper là gì? Đó là một phương pháp tĩnh nằm một cách đơn giản từ chính lớp đó.

Chúng tôi gặp phải vấn đề gì?

  1. phương pháp tĩnh. Có vấn đề với kiểm tra đơn vị. Ví dụ: nhà phát triển của chúng tôi đã thêm bộ nhớ đệm vào người trợ giúp. Kết quả là, không có khả năng chỉ đơn giản là giả lập các phương pháp này, trong khi tôi đã phải thêm vào nhiều logic chỉ để chế giễu đơn giản. Có, có một khả năng sử dụng sai phương pháp tĩnh ... nhưng lúc đầu không ai dự kiến ​​sẽ thêm trạng thái để trợ giúp.
  2. vị trí. Phương thức nằm trong một lớp khác, cách xa logic cơ bản. Đó là quan niệm sai về thiết kế mã.

Khi nào cần sử dụng trợ giúp? Khi bạn cần mở rộng thư viện của bên thứ ba mà không có khả năng kế thừa nó. Nếu không thì chỉ thừa hưởng lib.

Khi không sử dụng người trợ giúp? Để giảm mã trùng lặp. Bạn cần chuyển mã này sang một dịch vụ khác.Đọc về DDD để cải thiện kỹ năng tái cấu trúc và biết cách tổ chức dịch vụ theo cách tốt nhất

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