Làm thế nào để chúng ta biết để ủng hộ thành phần hơn khái quát hóa luôn luôn là lựa chọn đúng đắn?


9

Cho dù một đối tượng có tồn tại về mặt vật lý hay không, chúng ta có thể chọn mô hình hóa nó theo những cách khác nhau. Chúng ta có thể sử dụng khái quát hóa hoặc thành phần trong nhiều trường hợp. Tuy nhiên, nguyên tắc "ủng hộ thành phần trên tổng quát hóa [sic]" của GoF hướng dẫn chúng ta sử dụng thành phần. Vì vậy, khi chúng ta lập mô hình, ví dụ, một dòng thì chúng ta tạo một lớp có chứa hai thành viên PointA và PointB của loại Điểm (thành phần) thay vì mở rộng Điểm (khái quát hóa). Đây chỉ là một ví dụ đơn giản về cách chúng ta có thể chọn thành phần hoặc kế thừa một cách tự nhiên để làm mô hình, mặc dù các đối tượng đó thường phức tạp hơn nhiều.

Làm thế nào để chúng ta biết rằng đây là sự lựa chọn đúng đắn? Nó quan trọng ít nhất bởi vì có thể có một tấn tái cấu trúc để làm nếu nó sai?


9
Ví dụ của bạn không thực sự hoạt động vì bạn không thể nói một dòng là một điểm, và do đó nó không thành công Nguyên tắc thay thế Liskov và sự kế thừa là không phù hợp.
Dean Harding

@Dean: Như bạn có thể biết, ví dụ này không phải là trung tâm. Đối với bản ghi, một dòng có thể được biểu diễn dưới dạng một phương trình được xác định thông qua hai điểm.
CarneyCode


1
@Songo: Có vẻ như bạn đã hoàn toàn bỏ lỡ quan điểm.
CarneyCode

Không mở rộng chuyên môn hóa thay vì khái quát hóa?
Tulains Córdova

Câu trả lời:


17

Nó không phải luôn luôn là lựa chọn đúng đắn. Đây là một trong những thuận lợi trong hầu hết các trường hợp. Khi một mô hình tổng hợp yêu cầu thay đổi hoặc mở rộng, nó có khả năng chống lại đáng kể hơn bởi vì bạn có thể thay đổi thành phần mà không sợ ảnh hưởng đến các lớp khác một cách vô tình.

Làm sao chúng ta biết được điều này? Từ kinh nghiệm, và kinh nghiệm của người khác.

Tôi đã thấy nhiều tình huống trong đó một hệ thống phân cấp lớp lớn đã phát triển từ những gì bắt đầu như một khái niệm đơn giản, và đây là lúc việc tái cấu trúc chính của bạn trở nên cần thiết. Trong khi đó tôi chưa bao giờ thấy một tình huống trong đó một cấu trúc thành phần cần tái cấu trúc thành sự kế thừa.

Nhưng bằng chứng giai thoại của tôi không nên là đủ. Chỉ cần nhìn trên internet và một số người tốt đã có những trải nghiệm tương tự.


Tôi thích nó; mất một upvote.
CarneyCode

+1 cho "Tôi chưa bao giờ thấy một tình huống trong đó một cấu trúc thành phần cần tái cấu trúc thành thừa kế."
Kazark

7

Nếu bạn muốn một quy tắc mạnh hơn ngoài "thành phần ưu tiên hơn thừa kế" thì tôi có thể đề xuất một cái gì đó như thế này:

Trong hai cách để chuyên môn hóa một đối tượng - Kế thừa và Thành phần - bạn chỉ nên sử dụng tính kế thừa khi bạn cần đối tượng của mình là đa hình (có thể thay thế) cho lớp cơ sở mà bạn chuyên.

Tuy nhiên, giống như tất cả các quy tắc của ngón tay cái, một khi bạn hiểu quy tắc - thì bạn có thể tự do phá vỡ quy tắc :)


0

Tôi không thấy cách sáng tác và khái quát hóa là lựa chọn thay thế và không tìm được trích dẫn .
Thành phần và kế thừa là (để đạt được sự chuyên môn hóa), và có thể lập luận rằng sự trừu tượng hóa và khái quát hóa là (để đạt được tính mô đun hóa).

Những gì bạn muốn là thiết kế của bạn phải đơn giản và hợp lý, đó là hai phẩm chất vốn dễ dàng đo lường được.
Trong trường hợp của bạn, có vẻ hợp lý hơn khi soạn một dòng gồm hai điểm thay vì mở rộng nó, bởi vì bạn sẽ tự nhiên xác định một dòng bằng hai điểm, thay vì mở rộng khái niệm về một điểm.


Có tự nhiên hơn không? Một dòng không nhiều hơn hai điểm so với một điểm được mở rộng?
CarneyCode

2
Tôi chưa bao giờ thấy một định nghĩa dòng không bao gồm thực tế là nó được tạo từ hơn 2 điểm. Ngay cả khi sử dụng một phương trình của một dòng nếu bạn chỉ có 1 x giá trị trong miền số của bạn thì đó là một điểm, không phải là một dòng.
Giàn khoan

0

Ưu đãi xảy ra khi cả hai ứng cử viên đủ điều kiện. Vấn đề được nêu trong câu hỏi không thành công trên tài khoản này, bởi vì nó chỉ có tùy chọn thành phần.

"Thành phần cũng có thể sử dụng khái quát hóa". Liệu tuyên bố này có ý nghĩa với chúng tôi? Nếu không thì chúng ta vẫn chưa sẵn sàng để nắm bắt quy tắc 'ưu ái'.

Tại sao chúng tôi ủng hộ Thành phần là Thành phần cung cấp nhiều khả năng mở rộng / linh hoạt hơn so với khái quát hóa. Phần mở rộng / tính linh hoạt này chủ yếu đề cập đến thời gian chạy / tính linh hoạt động (đạt được với sự kết hợp của các giao diện và thành phần).

Lợi ích không thể nhìn thấy ngay lập tức. Để thấy được lợi ích, bạn cần đợi yêu cầu thay đổi bất ngờ tiếp theo. Vì vậy, trong hầu hết các trường hợp, những người gắn bó với khái quát hóa đều thất bại khi so sánh với những người chấp nhận sáng tác (ngoại trừ một trường hợp rõ ràng được đề cập sau). Do đó quy tắc. Từ quan điểm học tập nếu bạn có thể thực hiện tiêm phụ thuộc thành công thì bạn nên biết nên ưu tiên cái nào và khi nào. Quy tắc giúp bạn đưa ra quyết định khi bạn không chắc chắn nên chọn cái nào. Một lần nữa, bạn sẽ có thể thấy cả hai tùy chọn ở vị trí đầu tiên để ưu tiên một.

Tóm tắt: Thành phần: Khớp nối được giảm bằng cách chỉ cần một số thứ nhỏ hơn bạn cắm vào một cái gì đó lớn hơn và đối tượng lớn hơn chỉ gọi lại đối tượng nhỏ hơn. Tạo ra: Từ quan điểm API của bên thứ 3 xác định rằng một phương thức có thể bị ghi đè là một cam kết mạnh mẽ hơn so với việc xác định rằng một phương thức có thể được gọi (chắc chắn giành chiến thắng cho Tổng quát hóa). Và đừng bao giờ quên rằng với bố cục bạn cũng đang sử dụng khái quát hóa, từ một giao diện thay vì một lớp lớn. Nhưng toàn bộ tín dụng đi vào thành phần không may.


-4

Hôm nay tôi đã viết khoảng 300 LoC. Và tôi không thể nhớ bất kỳ nguyên tắc nào mà tôi có thể vi phạm và không vi phạm. Tái cấu trúc sẽ cứu linh hồn tôi, tôi hy vọng.

Nếu sự trừu tượng được quyết định bởi api bên 3d - thông thường việc sử dụng tính kế thừa là chính xác. Trong thực thể thiết kế trong nước phải là trừu tượng, hoặc niêm phong. Thực thể trừu tượng có khả năng phải có khoảng 3 người thừa kế. Tôi không thích các điểm mở rộng một phương thức ảo. Tất cả ở trên là về hương vị của tôi. Tôi không nói về sự trừu tượng hóa giao diện, đó là câu chuyện hoàn chỉnh khác nhau.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.