2010-09-26 28 views
6

Đôi khi sử dụng mixin với nhiều lần kế thừa có thể giúp chúng tôi cải thiện khả năng sử dụng lại mã của chúng tôi.Việc lạm dụng mixin là điều ác và các giải pháp thay thế là gì?

Ví dụ, việc thiết kế sau

class FollowableMixin(object): 
    def get_followers(self): 
     ... 
    ... 

class User(FollowableMixin): 
    ... 

có thể được tái sử dụng tốt hơn so với chỉ đơn giản là thêm get_followers để User:

class User(object): 
    def get_followers(self): 
     ... 
    ... 

vì sau đó chúng ta có thể xem xét hỗ trợ các đơn vị followable khác mà khách hàng tiềm năng của get_followers :

class BookStore(FollowableMixin): 
    ... 

Tuy nhiên, nếu mẫu này bị lạm dụng, mã có thể quá phức tạp.

class User(FollowableMixin, RunnableMixin, FlyableMixin, WhatMixin ...): 
    ... 

Với tất cả các lớp mixin này tiêm thuộc tính và phương thức vào lớp, bạn sẽ rất khó hiểu mã của mình. Ví dụ: bạn không biết phương thức bạn đang gọi đến từ đâu và phương pháp này lần lượt có thể bao gồm lời gọi phương thức trong một mixin khác ...

Tôi nên làm gì để đơn giản hóa chương trình này?

+2

Tôi không chắc chắn những gì "bị lạm dụng" có nghĩa là trong ngữ cảnh này. Nếu 'FollowableMixin' thích hợp với lớp' User', và 'RunnableMixin' là thích hợp, và ..., tuy nhiên, cần nhiều mixin, đó là số lượng bạn sử dụng. Bạn có thể gặp phải các xung đột về tên, nhưng đó chỉ là nếu bạn bất cẩn khi đặt tên cho các phương thức của mình. –

Trả lời

4

Sử dụng bộ điều hợp thay vì mixin. Vì vậy, trong trường hợp của bạn, bạn sẽ có một giao diện IFollowable và bộ điều hợp từ BookStore hoặc người dùng để IFollowable.

Xem http://ginstrom.com/scribbles/2009/03/27/the-adapter-pattern-in-python/ cho một mô tả bộ điều hợp trong Python và đặc biệt là các nhận xét từ Martijn Faassen về cách sử dụng nhà máy và giao diện và grokcore.component.

6

Đôi khi, nó có thể giúp thu thập các tính năng liên quan cùng nhau trong một lớp duy nhất nếu chúng thường được sử dụng cùng nhau.

class FooMixin(FollowableMixin, RunnableMixin): 
    pass 

Sau đó, khi bạn sử dụng, bạn chỉ có một hoặc hai lớp cơ sở trực tiếp thay vì nhiều lớp.

Rõ ràng bạn chỉ nên làm điều này nếu có ý nghĩa - nó có thể bị lạm dụng. Nếu không biết nhiều hơn về ví dụ cụ thể của bạn, thật khó để biết liệu nó có ý nghĩa để làm điều này hay không trong trường hợp của bạn.

5

Nếu lớp người dùng của bạn thực sự có nhiều đặc điểm thích hợp, thì bạn có thể chỉ đơn giản là có một ứng dụng phức tạp. Có năm mixin là tốt hơn so với năm chức năng sao chép từ những nơi khác.

Một số khả năng đơn giản hóa:

  1. lớp người dùng của bạn đang cố gắng làm quá nhiều. Chia nhỏ thành các lớp nhỏ hơn.

  2. Tổng hợp một số hỗn hợp của bạn. Ví dụ, bạn có thể tìm thấy có năm lớp học trong đó có thể theo dõi và Runnable và Flyable. Tạo một lớp trung gian FollowRunFly có nguồn gốc từ ba mixin đó, sau đó sử dụng FollowRunFly trong năm lớp của bạn.

  3. Có lẽ bạn không cần phải cắt các hỗn hợp của bạn sao cho mịn. Tạo một mixin lớn, và sử dụng nó trên các lớp của bạn, và để cho mã xác định trong thời gian chạy cho dù đối tượng có thể bay hay được theo sau.

3

Với giấy và bút chì, hãy ghi lại các lớp cụ thể thực sự được tạo ra (ví dụ: Người dùng và BookStore). Liệt kê tất cả các phương thức mà bạn muốn các lớp đó thực hiện. Chỉ bằng cách xem danh sách này, bạn có thể quyết định hợp lý thứ bậc lớp nào phù hợp nhất với tình huống của bạn. Sự chậm chạp của việc viết bằng tay có thể buộc bạn phải suy nghĩ về mối quan hệ giữa các đối tượng của bạn theo một cách mới. Hãy thử giải thích các lớp học của bạn một cách chi tiết cho một người bạn tưởng tượng (hoặc chúng tôi!), Những người thông minh nhưng không biết gì về vấn đề của bạn. Sự chậm chạp của việc nêu rõ các chi tiết có thể dẫn đến sự thấu hiểu.

Hỗn hợp có thể cung cấp cho bạn nhiều tính tổng quát để cho phép dự án phát triển, nhưng bạn thường bị buộc phải thỏa hiệp giữa tính tổng quát (phức tạp) và thực tiễn (thường đơn giản hơn). Bốn mixin cho phép 2 ** 4 lớp bê tông có thể. Nếu trong thực tế bạn có ít hơn các lớp cụ thể, sau đó mixin có thể không phải là công cụ thích hợp cho công việc.

Nếu bạn cảm thấy tính tổng quát đang áp đảo bạn, tôi nghĩ sẽ rất khôn ngoan để loại bỏ tính tổng quát, đóng băng các tính năng và mã theo cách đơn giản nhất để chứa các tính năng đó. Sau đó, khi bạn có một sản phẩm làm việc, bạn có thể suy nghĩ về việc thêm các tính năng mới và tái cấu trúc nếu cần thiết.

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