2012-02-14 34 views
5

Giả sử tôi có một đối tượng, Ô tô, và nó có tập hợp các phương thức khác nhau ...? Có thể nhận được Blob như thế nào? (như trong các antipattern, "blob") Những phương pháp này hoạt động trong bộ đủ riêng biệt và không thực sự chéo chéo chức năng.Phương pháp mới đi đâu?

Car 
# methods related to suburban driving 
    ->foo1 
    ->foo2 
# methods related city driving 
    ->bar3 
    ->bar4 

Bây giờ, giả sử tôi muốn thêm "tắt đường lái xe" là một trong những trường hợp đối tượng xe của tôi có thể hỗ trợ. Nếu tôi thêm các phương thức vào đối tượng Ô tô, không phải là làm cho nó trở nên blob hơn?

Car (augmented) 
# methods related to suburban driving 
    ->foo1 
    ->foo2 
# methods related city driving 
    ->bar3 
    ->bar4 
# methods related off road driving 
    ->blah5 
    ->blah6 

Tôi có nên:

A: Subclass xe. Tôi có thể làm cho một OffRoadCar mở rộng đối tượng xe. Nhưng nếu Car và OffRoadCar chia sẻ cùng một dữ liệu/trạng thái và chỉ khác nhau theo phương pháp thì sao? OffRoadCar chỉ "hoạt động" cụ thể hơn xe hơi, nhưng không được mô tả cụ thể hơn và cũng không có trường duy nhất. Vì vậy, instantiating một OffRoadCar là vô nghĩa.

OffRoadCar extends Car 
# methods related off road driving 
    ->blah5 
    ->blah6 

B: Tiêu thụ xe bằng phương pháp tĩnh. Giống như OffRoadAdventure-> Embark (Car). Vì vậy, lớp OffRoadAdventure mất một đối tượng Ô tô và có cách của nó với nó.

Trong C#, điều này sẽ được gọi là phương pháp mở rộng.

Tôi đoán đặt một cách khác là giải pháp cho đối tượng Blob antipattern là gì? Là phân lớp? Có phương pháp mở rộng không?

Ngoài ra, một lý do khác mà tôi muốn giải quyết các phương pháp này là điều gì sẽ xảy ra nếu việc triển khai thực hiện một số chi phí, như bao gồm các gói/gói khác? Tôi sẽ không muốn người dùng của lớp cốt lõi liên tục trả tiền cho thứ mà họ sẽ không bao giờ sử dụng. Tôi hình dung chi phí cho thiểu số là đáng để tiết kiệm cho đa số. Và nó làm cho biểu đồ phụ thuộc chính xác hơn (và không giống blob).

PS - Ngôn ngữ triển khai là Perl.

+0

Xe hơi có phải là một lớp học không? Có thể xe thực sự là một ICar (giao diện)? Tôi sẽ đề xuất một lộ trình thành phần trên thừa kế. – OnResolve

+0

Ô tô đã là một lớp thực sự đang được sử dụng. (nó thực sự là một hiện vật ORM) –

Trả lời

0

Tôi nghĩ bạn đang đi đúng hướng. Một giải pháp thanh lịch là có OffRoadCar được kế thừa từ Ô tô và ghi đè phương thức Drive() của nó. Bằng cách đó, bạn có thể nói:

Car myCar = new OffRoadCar(); 
myCar.Drive(); 

này sẽ gọi ghi đè Drive() phương pháp trong các lớp con, và bạn không kết thúc với một phương pháp gazillion trong một "blob" duy nhất. Dưới đây là cách Drive() phương pháp trong OffRoadCar thể trông giống như:

@Override 
public void Drive() 
{ 
/* code */ 
} 
2

Với Perl bạn nên tham gia một cái nhìn tốt ở Moose và vai trò.

package Suburban; 
use Moose::Role; 

requires 'wheels'; 

sub 'foo1' { 
    ... 
} 


sub 'foo2' { 
    ... 
} 

package City; 
use Moose::Role; 

requires 'wheels'; 

sub 'bar3' { 
    ... 
} 


sub 'bar4' { 
    ... 
} 

package Offroad; 
use Moose::Role; 

requires 'wheels'; 

sub 'blah5' { 
    ... 
} 


sub 'blah6' { 
    ... 
} 

package UltraCar; 
use Moose; 

with qw/ Offroad City Suburban /; 
has 'wheels' => (is => 'rw', isa => 'Int', default => 4); 

package RentalCar; 
use Moose; 

with qw/ City Suburban /; 
has 'wheels' => (is => 'rw', isa => 'Int', default => 4); 

package Tricycle; 
use Moose; 

with qw/ Offroad /; 
has 'wheels' => (is => 'rw', isa => 'Int', default => 3); 

Bạn thậm chí có thể thêm và xóa vai trò khi chạy.

+1

Làm thế nào để giải quyết vấn đề blob? Vai trò/giao diện dành cho các lớp khác nhau hoàn thành cùng một hợp đồng. –

+1

Vấn đề với blob là bạn đang lăn tất cả các chức năng của đối tượng vào một vị trí duy nhất. Sử dụng vai trò cho phép bạn chia nhỏ các tính năng khác nhau thành các mô-đun mã riêng biệt, có thể kiểm tra, sau đó áp dụng chúng cho các đối tượng của bạn khi cần. Vào thời gian chạy, vâng, bạn vẫn còn có 'đối tượng thần thánh', nhưng vào thời điểm đó bạn không thực sự lo lắng về điều đó, bởi vì các vấn đề với antipattern đó là: phát triển. Vì bạn có thể áp dụng vai trò trong thời gian chạy, bạn cũng có thể thêm chỉ cuộn chức năng bạn cần và không cần phải thực hiện các lần truy cập không cần thiết. – Oesor

+0

Chỉnh sửa của bạn đã rõ ràng hơn. Nhưng theo một số hạn chế kỹ thuật, chúng tôi không thể sử dụng Moose. Tôi có được những gì bạn đang nói mặc dù. –

0

Thay vì phân lớp lớp Car, bạn có thể sử dụng một số hình thức Decorator pattern.

Ở đây, lớp ORM cơ sở và trang trí (nói OffRoadDecorator) triển khai một số giao diện chung và hành vi của mỗi trang trí có thể được thêm động vào lớp gốc.

Sự khác biệt chính ở đây là nhiều trang trí có thể được sử dụng trên cùng một lớp Car và tùy thuộc vào việc triển khai của bạn để cho biết cách những người tương tác nên tương tác. Không có gì để ngăn bạn trang trí lớp học của bạn bằng cách sử dụng OffRoadDecorator cũng như SuburbanDecorator và bạn có thể quyết định chính xác ý nghĩa của chiếc xe trong trang trí.

(PS xin lỗi tôi không cung cấp bất kỳ ví dụ mã; Perl của tôi chỉ đơn giản là khủng khiếp Có một cái nhìn tại this page cho một số ví dụ khác..)

0

Không thực sự là một câu trả lời Mark và tôi không chắc chắn cách sâu sắc bạn muốn đi sâu vào điều này, nhưng bạn có thể xem xét ý tưởng về Thứ tự phân giải phương pháp. Thay vì độ sâu tiêu chuẩn tìm kiếm phương pháp đầu tiên, sử dụng mro cho phép bạn thực hiện tìm kiếm đầu tiên trên bề rộng. Xem this page trên CPAN và brian d foy bài viết Use the C3 method resolution order in multiple inheritance để biết thêm.

0

Ngoại ô, thành phố và ngoại tuyến Âm thanh lái xe như thuật toán. Mẫu chiến lược có thể trợ giúp ở đây với bối cảnh là ô tô.

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