Có hai cách trong đó các lớp cơ sở trừu tượng được sử dụng.
Bạn đang chuyên về đối tượng trừu tượng của mình, nhưng tất cả các máy khách sẽ sử dụng lớp dẫn xuất thông qua giao diện cơ sở của nó.
Bạn đang sử dụng một lớp cơ sở trừu tượng để tạo ra sự trùng lặp trong các đối tượng trong thiết kế của mình và khách hàng sử dụng các triển khai cụ thể thông qua các giao diện của riêng họ.!
Giải pháp cho 1 - Mô hình chiến lược
Nếu bạn có tình huống đầu tiên, thì bạn thực sự có một giao diện được xác định bởi các phương thức ảo trong lớp trừu tượng mà các lớp dẫn xuất của bạn đang thực hiện.
Bạn nên xem xét việc biến nó thành một giao diện thực sự, thay đổi lớp trừu tượng của bạn thành cụ thể và lấy một thể hiện của giao diện này trong hàm tạo của nó. Các lớp dẫn xuất của bạn sau đó trở thành triển khai của giao diện mới này.
Điều này có nghĩa là bây giờ bạn có thể kiểm tra lớp trừu tượng trước đây của mình bằng cách sử dụng một phiên bản giả của giao diện mới và mỗi lần thực hiện mới thông qua giao diện công khai. Mọi thứ đều đơn giản và có thể kiểm chứng.
Giải pháp cho 2
Nếu bạn có tình huống thứ hai, thì lớp trừu tượng của bạn đang hoạt động như một lớp trợ giúp.
Hãy xem chức năng của nó. Xem nếu bất kỳ của nó có thể được đẩy lên các đối tượng đang được thao tác để giảm thiểu sự trùng lặp này. Nếu bạn vẫn còn bất cứ thứ gì, hãy xem làm cho nó trở thành một lớp trợ giúp mà việc triển khai cụ thể của bạn có trong hàm tạo của chúng và loại bỏ lớp cơ sở của chúng.
Điều này một lần nữa dẫn đến các lớp cụ thể đơn giản và dễ kiểm tra.
Như một quy luật
Ưu tiên mạng phức tạp của các đối tượng đơn giản trên một mạng đơn giản của các đối tượng phức tạp.
Chìa khóa để mở rộng mã có thể kiểm tra là các khối xây dựng nhỏ và hệ thống dây độc lập.
Cập nhật: Làm thế nào để xử lý hỗn hợp của cả hai?
Có thể có một lớp cơ sở thực hiện cả hai vai trò này ... tức là: nó có giao diện chung và có các phương thức trợ giúp được bảo vệ. Nếu đây là trường hợp, thì bạn có thể tính ra các phương thức của trình trợ giúp thành một lớp (kịch bản 2) và chuyển đổi cây thừa kế thành một mẫu chiến lược.
Nếu bạn thấy bạn có một số phương thức mà lớp cơ sở của bạn thực hiện trực tiếp và các phương thức khác là ảo, thì bạn vẫn có thể chuyển đổi cây thừa kế thành một mẫu chiến lược, nhưng tôi cũng sẽ coi đó là một chỉ báo tốt rằng các trách nhiệm không được căn chỉnh chính xác và có thể cần tái cấu trúc.
Cập nhật 2: Các lớp trừu tượng như một bước đệm (2014/06/12)
Tôi đã có một tình huống vào ngày khác khi tôi sử dụng trừu tượng, vì vậy tôi muốn khám phá lý do tại sao.
Chúng tôi có một định dạng tiêu chuẩn cho các tập tin cấu hình của chúng tôi. Công cụ đặc biệt này có 3 tệp cấu hình tất cả ở định dạng đó. Tôi muốn một lớp được gõ mạnh cho mỗi tệp cài đặt vì vậy, thông qua việc tiêm phụ thuộc, một lớp có thể yêu cầu các cài đặt mà nó quan tâm.
Tôi đã thực hiện điều này bằng cách có một lớp cơ sở trừu tượng biết cách phân tích các định dạng tệp cài đặt và các lớp dẫn xuất tiếp xúc với các phương thức đó, nhưng đóng gói vị trí của tệp cài đặt.
Tôi có thể đã viết một "SettingsFileParser" rằng 3 lớp được bao bọc, và sau đó được ủy quyền cho lớp cơ sở để hiển thị các phương thức truy cập dữ liệu. Tôi quyết định không làm điều này nhưng vì nó sẽ dẫn đến 3 các lớp thừa kế với nhiều đoàn đại biểu mã trong họ hơn bất cứ điều gì khác.
Tuy nhiên ... khi mã này phát triển và người tiêu dùng của mỗi lớp cài đặt này trở nên rõ ràng hơn. Mỗi cài đặt người dùng sẽ yêu cầu một số cài đặt và chuyển đổi chúng theo một cách nào đó (vì cài đặt là văn bản, họ có thể gói chúng trong các đối tượng chuyển đổi chúng thành số, v.v.). Khi điều này xảy ra, tôi sẽ bắt đầu trích xuất logic này vào các phương thức thao tác dữ liệu và đẩy chúng trở lại các lớp cài đặt được gõ mạnh. Điều này sẽ dẫn đến một giao diện cấp cao hơn cho mỗi bộ cài đặt, mà cuối cùng không còn biết nó đang xử lý 'cài đặt'.
Tại thời điểm này, các lớp cài đặt được gõ mạnh sẽ không còn cần các phương thức "getter" để lộ triển khai 'cài đặt' bên dưới.
Tại thời điểm đó tôi sẽ không còn muốn giao diện chung của chúng bao gồm các phương thức truy cập cài đặt; vì vậy tôi sẽ thay đổi lớp này để đóng gói một trình phân tích cú pháp cài đặt thay vì xuất phát từ nó.
Do đó, lớp Trừu tượng là: một cách để tôi tránh mã ủy nhiệm tại thời điểm này và một điểm đánh dấu trong mã để nhắc tôi thay đổi thiết kế sau này. Tôi có thể không bao giờ nhận được nó, vì vậy nó có thể sống tốt trong khi ... chỉ có mã mới có thể biết.
Tôi thấy điều này đúng với bất kỳ quy tắc nào ... như "không có phương thức tĩnh" hoặc "không có phương thức riêng tư". Chúng chỉ ra một mùi trong mã ... và điều đó thật tốt. Nó giúp bạn tìm kiếm sự trừu tượng mà bạn đã bỏ lỡ ... và cho phép bạn tiếp tục cung cấp giá trị cho khách hàng của mình trong thời gian đó.
Tôi tưởng tượng các quy tắc như thế này xác định một cảnh quan, nơi mã duy trì sống trong các thung lũng. Khi bạn thêm hành vi mới, nó giống như mưa rơi vào mã của bạn. Ban đầu bạn đặt nó ở bất cứ nơi nào nó hạ cánh .. sau đó bạn tái cấu trúc để cho phép các lực lượng có thiết kế tốt đẩy hành vi xung quanh cho đến khi tất cả kết thúc ở các thung lũng.