Tại sao phân lớp quá xấu (và do đó tại sao chúng ta nên sử dụng các nguyên mẫu để loại bỏ nó)?


10

Tôi đã đọc các mẫu thiết kế và tôi đọc rằng mẫu thiết kế nguyên mẫu không còn phân lớp quá mức.

Tại sao phân lớp xấu? Lợi thế nào khi sử dụng một nguyên mẫu sẽ mang lại hơn phân lớp?


Nói ai ? bạn có một liên kết?
Camus

Tôi đã đọc p.118 của cuốn sách này. goo.gl/6JGw1
David Faux

Câu trả lời:


19

Tại sao phân lớp quá nhiều xấu

"Quá nhiều" là một lời kêu gọi phán xét; nhưng lấy nó từ tôi thì nó tệ Mã tôi làm việc có thừa kế DEEP và mã này rất khó đọc, hiểu, theo dõi, theo dõi, gỡ lỗi, v.v ... Thật sự không thể viết mã kiểm tra cho công cụ này.

Mẫu thử nghiệm không có phân lớp

Hay câu hỏi có nghĩa là "không có quá nhiều phân lớp?". Mẫu này yêu cầu nhân bản một đối tượng "mẫu" để tránh phân lớp, ít nhất là tại thời điểm đó. Không có quy tắc nào nói rằng "mẫu" không thể là một lớp con.

Thành phần ủng hộ thừa kế

Ý tưởng này ở đây cũng bao gồm đoàn và tổng hợp. Theo heuristic này có nghĩa là phần mềm của bạn có xu hướng linh hoạt hơn, dễ bảo trì, mở rộng và tái sử dụng hơn.

Khi một lớp bao gồm các phần, bạn có thể thay thế các phần đó trong thời gian chạy . Điều này có ảnh hưởng sâu sắc đến khả năng kiểm tra.

Kiểm tra dễ dàng hơn . Bạn có thể sử dụng các bộ phận giả (tức là "giả", "nhân đôi" và nói chuyện thử nghiệm khác). Kế thừa sâu sắc của mã của chúng tôi có nghĩa là chúng tôi phải khởi tạo toàn bộ hệ thống phân cấp để kiểm tra bất kỳ bit nào của nó. Trong trường hợp của chúng tôi, điều đó là không thể nếu không chạy mã trong môi trường thực của nó. Ví dụ, chúng ta cần một cơ sở dữ liệu để khởi tạo các đối tượng kinh doanh.

Các thay đổi đi kèm với các tác dụng phụ và sự không chắc chắn - Lớp càng "cơ sở" thì các hiệu ứng càng lan rộng, tốt hay xấu. Có thể có những thay đổi mong muốn mà bạn không dám thực hiện do không chắc chắn về tác dụng phụ. Hoặc một thay đổi tốt cho một nơi nào đó trong chuỗi thừa kế của chúng tôi là xấu cho một nơi khác. Đây chắc chắn là kinh nghiệm của tôi.


Tôi thực sự thích thú khi thấy một số ví dụ về việc khi thừa kế làm cho việc kiểm tra (đặc biệt là chế giễu) trở nên khó khăn và cách thức sáng tác giúp điều đó.
Armand

@alison: Một Phương thức trong lớp dẫn xuất sử dụng một phương thức khác từ lớp cơ sở nơi việc triển khai trong lớp cơ sở làm cho hầu như không thể kiểm tra các kịch bản lỗi. Nếu đó là thành phần thì việc tiêm một đối tượng sẽ gây ra lỗi dễ dàng hơn
Rune FS

@allison: Ví dụ? Khi cơ sở mã là rất lớn, khi các lớp cơ sở được sử dụng bởi hàng chục lớp trực tiếp và hàng trăm theo kế thừa. Bởi vì điểm kế thừa sâu là tái sử dụng và do đó, một lớp cơ sở được khái quát hóa đến mức mà dấu vết ngăn xếp trình gỡ lỗi không thể hiển thị phương thức nào thực sự được gọi. Cuối cùng, khi không có tiêm phụ thuộc đã được tích hợp vào Frankenstein như vậy. Một lớp cấp cao nhất có thể "là" một nửa tá hoặc nhiều thứ khác mà chung "có" hàng tá đối tượng bên trong - mỗi đối tượng có ngôi nhà vui vẻ thừa kế riêng.
radarbob

8

Tôi nghĩ một trong những lý do điều này được xem là một thực tiễn tồi tệ là theo thời gian, mỗi lớp con có thể chứa các thuộc tính và phương thức không có ý nghĩa đối với đối tượng đó khi bạn đi xuống chuỗi (trong hệ thống phân cấp kém phát triển). Bạn có thể kết thúc với một lớp cồng kềnh chứa các vật phẩm không có ý nghĩa đối với lớp đó.

Tôi không biết gì về bản thân mình. Có vẻ như giáo điều chỉ nói rằng nó xấu. Bất cứ điều gì là xấu khi sử dụng sai.


2

Hai lý do.

  1. Là hiệu suất thời gian chạy. Mỗi khi bạn gọi một lớp con từ một siêu lớp bạn đang thực hiện một cuộc gọi phương thức, vì vậy nếu bạn đã lồng năm lớp và gọi một phương thức trong lớp cơ sở, bạn sẽ thực hiện năm lần gọi phương thức. Hầu hết các trình biên dịch / thời gian chạy sẽ cố gắng nhận ra điều này và tối ưu hóa các cuộc gọi thêm nhưng chỉ an toàn để làm điều này cho các trường hợp rất đơn giản.

  2. Là sự tỉnh táo của các lập trình viên đồng bào của bạn. Nếu bạn lồng năm lớp, tôi phải kiểm tra tất cả bốn lớp cha để xác lập bạn thực sự đang gọi một phương thức trong lớp cơ sở, điều đó thật tẻ nhạt. Tôi cũng có thể phải bước qua năm lần gọi phương thức khi gỡ lỗi chương trình.


6
-1: Bạn đúng về # 2; nhưng không phải về # 1. Một số lớp kế thừa sẽ không nhất thiết ảnh hưởng đến hiệu suất thời gian chạy.
Jim G.

Lo lắng về một vài cuộc gọi thủ tục bổ sung ở cấp mã máy và sử dụng OP và thừa kế, và bạn lo lắng về sự tỉnh táo của các lập trình viên đồng nghiệp của mình .....
mattnz

@JimG. Nó có thể không, nhưng nó có thể. :) Cũng có thể sử dụng bộ nhớ để lo lắng: nếu bạn không sử dụng lại tất cả các biến cơ sở, chúng vẫn có thể được phân bổ như một phần của việc xây dựng đối tượng.
Adam Lear

2

"Quá nhiều" là một cuộc gọi phán xét.

Như với hầu hết mọi thứ trong lập trình, việc phân lớp không hẳn là xấu khi nó có ý nghĩa. Khi mô hình giải pháp vấn đề của bạn có ý nghĩa hơn như là một hệ thống phân cấp hơn là một thành phần của các bộ phận, phân lớp có thể là tùy chọn ưa thích.

Điều đó nói rằng, ủng hộ thành phần hơn thừa kế là một quy tắc tốt.

Khi bạn phân lớp, việc kiểm tra có thể khó khăn hơn (như radarbob đã lưu ý ). Trong một hệ thống phân cấp sâu, việc cô lập mã có vấn đề khó khăn hơn vì việc tạo một lớp con đòi hỏi phải đưa vào toàn bộ hệ thống phân cấp siêu lớp và một loạt các mã bổ sung. Với cách tiếp cận thành phần, bạn có thể cô lập và kiểm tra từng thành phần của đối tượng tổng hợp của mình bằng các thử nghiệm đơn vị, các đối tượng giả, v.v.

Phân lớp cũng có thể khiến bạn tiết lộ chi tiết về việc triển khai mà bạn có thể không muốn. Điều này gây khó khăn cho việc kiểm soát quyền truy cập vào biểu diễn cơ bản của dữ liệu của bạn nó ràng buộc bạn với việc triển khai cụ thể mô hình sao lưu của bạn.

Một ví dụ tôi có thể nghĩ đến là java.util.ProperIES, kế thừa từ Hashtable. Lớp Properties chỉ nhằm lưu trữ các cặp Chuỗi-Chuỗi (điều này được ghi chú trong Javadocs). Do tính kế thừa, các phương thức put và putAll từ Hashtable đã được hiển thị cho người dùng Thuộc tính. Mặc dù cách "đúng" để lưu trữ một thuộc tính là với setProperty (), nhưng hoàn toàn không có gì ngăn người dùng gọi put () và chuyển vào Chuỗi và Đối tượng.

Về cơ bản, ngữ nghĩa của Thuộc tính được xác định kém vì tính kế thừa. Ngoài ra, nếu bất kỳ ai muốn thay đổi đối tượng sao lưu cho Thuộc tính, tác động sẽ có tác động lớn hơn nhiều đối với mã sử dụng Thuộc tính so với khi Thuộc tính đã thực hiện một cách tiếp cận thành phần hơn.


2

Kế thừa có thể phá vỡ đóng gói trong một số trường hợp, và nếu điều đó xảy ra thì thật tệ. Đọc để biết thêm.


Ngày xưa không có sự kế thừa, một thư viện sẽ xuất bản API và ứng dụng sử dụng nó để sử dụng những gì hiển thị công khai và giờ đây thư viện có cách riêng để xử lý các bánh răng bên trong luôn thay đổi mà không phá vỡ Ứng dụng.

Khi nhu cầu phát triển, thư viện có thể phát triển và có thể có nhiều khách hàng hơn; hoặc nó có thể cung cấp chức năng mở rộng bằng cách kế thừa từ lớp riêng của nó với các hương vị khác. Càng xa càng tốt.

Tuy nhiên, điều cơ bản là, nếu một ứng dụng chiếm lớp và bắt đầu phân lớp nó, thì bây giờ một lớp con thực sự là một máy khách chứ không phải là một đối tác nội bộ. Tuy nhiên, không giống như một cách rõ ràng rõ ràng mà API công khai được xác định, lớp con bây giờ sâu hơn nhiều trong thư viện (truy cập vào tất cả các biến riêng tư, v.v.). Điều đó không phải là xấu, nhưng một nhân vật khó chịu có thể kết nối một API quá nhiều trong APP cũng như trong thư viện-

Về bản chất trong khi điều này có thể không phải luôn luôn như vậy nhưng,

Thật dễ dàng để lạm dụng thừa kế để phá vỡ đóng gói

Cho phép phân lớp có thể sai nếu điểm đó.


1

Trả lời nhanh:

Nó phụ thuộc vào những gì bạn đang làm.

Câu trả lời nhàm chán mở rộng:

Một nhà phát triển có thể làm cho một ứng dụng. sử dụng một trong hai, phân lớp hoặc mẫu (nguyên mẫu). Đôi khi một kỹ thuật hoạt động tốt hơn. Đôi khi các techinque khác hoạt động tốt hơn.

Việc lựa chọn với kỹ thuật hoạt động tốt nhất, cũng đòi hỏi, phải xem xét nếu một kịch bản "Đa kế thừa" hiện tại. Ngay cả khi ngôn ngữ lập trình chỉ hỗ trợ kế thừa, mẫu hoặc nguyên mẫu duy nhất.

Ghi chú bổ sung:

Một số câu trả lời liên quan đến "nhiều kế thừa". Suy nghĩ, không phải là câu hỏi chính, nó liên quan đến chủ đề. Có một số bài viết tương tự về "thừa kế so với thành phần". Tôi đã có một trường hợp tôi trộn cả hai.

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.