Làm cách nào để tránh viết nhiều hàm truyền qua trong trình bao bọc?


13

Tôi có một lớp, nó bao bọc một lớp khác của một loại cơ sở chung. Bởi vì giao diện loại cơ sở khá lớn, điều này liên quan đến việc viết rất nhiều hàm truyền qua. Tôi đang tìm cách để tránh điều này.

Hãy làm một ví dụ:

      Car
     /   \
Volvo     VolvoWithTrailer

Bây giờ tôi phải triển khai từng chức năng trong giao diện xe hơi cho VolvoWithTrailer và gọi chức năng phù hợp trên đối tượng Volvo được bao bọc ngoại trừ có thể GetMaxSpeed ​​() sẽ trả về giá trị thấp hơn. Về cơ bản tôi sẽ có nhiều chức năng như

int VolvoWithTrailer::GetNumSeats() {
  return mVolvo.GetNumSeats()
}

Một cách rõ ràng để giải quyết vấn đề này là biến VolvoWithTrailer thành một lớp con của Volvo

    Car
     |
   Volvo
     |
VolvoWithTrailer

nhưng điều đó dường như vi phạm nguyên tắc ủng hộ thành phần hơn thừa kế.

Làm thế nào khác tôi có thể tránh viết tất cả các hàm bao (ngôn ngữ là C ++)? Hoặc - nếu đó là vị trí của bạn - tại sao tôi chỉ nên viết chúng / chỉ sử dụng tính kế thừa? Có phép thuật mẫu nào có thể giúp với điều này?


2
Mặc dù điều này quá nhiều và suy nghĩ trong Java. Giao diện 'Trailer' thì sao? VolvoWithTrailer sẽ mở rộng Volvo và triển khai giao diện Trailer?

7
Thành phần ủng hộ hơn thừa kế chỉ khi nó có ý nghĩa để làm như vậy.
Robert Harvey

@RobertHarvey: +1. Đó là một hướng dẫn, không phải là "nguyên tắc", và chắc chắn không phải là một điều răn tuyệt đối.
Mason Wheeler

Trong Python, bạn có thể giải quyết vấn đề này bằng cách xem xét nội tâm (cái mà C # gọi là sự phản chiếu).
dùng16764

1
IDE của bạn không xử lý việc tạo mã?
Amy Blankenship

Câu trả lời:


5

Ý kiến ​​của tôi là bạn nên viết bất cứ điều gì bạn cần viết để làm cho sự ổn định lâu dài và khả năng duy trì của chương trình tốt hơn. Điều gì là lý do để tránh viết 20 dòng mã ngày hôm nay, nếu mỗi lần bạn chạm vào thứ gì đó sử dụng mã này hoặc quay lại để duy trì Lớp này, bạn sẽ mất thêm 5 phút hoặc hơn vì bạn không đặt thời gian hôm nay?

Vì vậy, câu hỏi sau đó trở thành "bạn cần viết gì?" Tôi không nghĩ rằng bạn cung cấp đủ thông tin để có thể đưa ra câu trả lời dứt khoát, vì vậy tôi sẽ chỉ liệt kê một số điều mà tôi sẽ nghĩ về việc đưa ra quyết định:

1. Bạn có cần phải có đối tượng Trailer một mình, bây giờ hoặc trong tương lai gần?
Nếu vậy, bạn có một đối số khá tốt để tạo trình bao bọc xung quanh cả hai đối tượng tổng hợp, vì bạn đã phải bọc cái này hay cái kia. Cũng có thể là nhất quán.

2. Có bất kỳ loại nào trong ba loại (Xe hơi, Đoạn giới thiệu, CarWithTrailer) trong một khu vực của mã mà các nhà phát triển thường xuyên sử dụng hoặc có vẻ như trở nên như vậy không?
Nếu vậy, hãy thật cẩn thận, bởi vì sự phân nhánh của việc chọn sai có thể được khấu hao rất tốn kém mỗi khi mã được chạm vào. Nếu không, nó có thể không làm cho bất kỳ sự khác biệt những gì bạn quyết định. Chỉ cần chọn một hướng và đi với nó.

3. Điều gì dễ hiểu nhất?
Có một cách tiếp cận nhảy ra với bạn rằng ai đó đến sau bạn sẽ ngay lập tức "hiểu" những gì bạn đang cố gắng làm? Các đồng đội của bạn có những thành kiến ​​đặc biệt nào có thể khiến họ khó tiếp cận hơn không? Nếu tất cả mọi thứ đều bằng nhau, hãy chọn giải pháp áp đặt tải nhận thức thấp nhất.

4. Có bất kỳ lợi thế bổ sung nào khi sử dụng một phương pháp này so với phương pháp khác không?
Một điều làm tôi ngạc nhiên là ý tưởng trình bao bọc có một lợi thế khác biệt nếu bạn viết rằng CarWithTrailerWrapper của bạn có thể bọc bất kỳ chiếc xe và bất kỳ đoạn giới thiệu nào vào CarWithTrailer. Sau đó, bạn kết thúc việc viết tất cả các phương thức chuyển qua của mình, nhưng bạn chỉ viết chúng một lần , thay vì một lần cho mỗi Loại xe.

Điều này làm cho khoản đầu tư ban đầu của bạn vào việc viết các phương thức chuyển qua rẻ hơn rất nhiều khi bạn thêm nhiều Xe và Rơ moóc. Nó cũng giúp giảm sự cám dỗ để kết nối trực tiếp mọi thứ với Volvo hoặc VolvoWithTrailer, đồng thời giảm hậu quả của việc ghép nối với CarWithTrailerWrapper, vì bạn có thể thực hiện nhiều hơn chỉ với một lần thực hiện.

Có thể có những lợi thế riêng biệt mà bạn có được miễn phí bằng cách sử dụng phương thức tiện ích mở rộng, nhưng tôi không thấy chúng.

OK, vì vậy có vẻ như tôi đã nói về bản thân mình để đi trước và điền vào các phương thức chuyển qua, cho các ứng dụng không tầm thường.

Tôi không phải là lập trình viên C ++, vì vậy tôi không biết công cụ tạo mã nào có sẵn cho bạn. IDE tôi sử dụng có thể tạo các phương thức từ Giao diện và tôi có thể thêm các mẫu mã sẽ giúp việc viết vượt qua trở nên không gây đau đớn. Nếu bạn không có quyền truy cập vào IDE thực hiện điều này, bạn thực sự có thể đi khá xa để Excel viết mã cho bạn .


3

Bởi vì giao diện loại cơ sở khá lớn, điều này liên quan đến việc viết rất nhiều hàm truyền qua.

Và có vấn đề của bạn.

Giao diện chỉ nên xử lý một trách nhiệm. Giữ cho chúng mỏng và tập trung giới hạn số lượng công việc vượt qua mà bạn có thể cần phải làm trong trường hợp trang trí, proxy hoặc trình bao bọc khác (ngoài việc tạo trình mô phỏng lớp để sử dụng, kiểm tra, bảo trì và mở rộng).


5
À, cái gì? Một Class có thể thực hiện nhiều giao diện và các giao diện có thể kế thừa từ nhau. Vì vậy, ngay cả khi một Giao diện khá nhỏ, điều đó không liên quan gì đến việc các Lớp có triển khai chúng hay không sẽ cần rất nhiều hàm hoặc các hàm truyền qua. Nhỏ hơn và nhiều hơn nữa cũng xác định các lớp học , nhiều khả năng nó sẽ trở thành mà bạn sẽ cần pass-through chức năng.
Amy Blankenship
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.