2010-03-18 30 views
5

Tôi đang tìm hiểu về các mẫu thiết kế và trong các ví dụ mã tôi đã nhìn thấy một quy ước nơi lớp trừu tượng khai báo một phương pháp, ví dụ:trừu tượng chữ ký phương pháp, thừa kế, và "Thực hiện" quy ước đặt tên

public abstract class ServiceBase { 
... 

public virtual object GetSomething(); 

và sau đó

protected abstract object DoGetSomething(); 

Câu hỏi của tôi là lý do tại sao hai phương pháp này tồn tại vì chúng có cùng mục đích. Điều này sao cho lớp cơ sở của lớp cơ sở GetSomething() không thể bị ghi đè bởi các lớp kế thừa? Nhưng sau đó một lần nữa, phương pháp được đánh dấu ảo, vì vậy nó có thể được ghi đè anyway. Tính hữu dụng ở đây trong việc yêu cầu những người triển khai lớp dẫn xuất để thực hiện phương thức trừu tượng khi phương thức ảo có thể được gọi là gì?

+0

GetSomething có phải là ảo không? – JaredPar

+0

Vâng, nó chắc chắn là ảo. –

Trả lời

4

Một lý do phổ biến là đặt xử lý chuẩn xung quanh phương pháp trừu tượng. Ví dụ, có lẽ phương pháp trừu tượng chỉ có thể được gọi trong một hoàn cảnh nhất định - giả sử, sau khi các đường splines đã được kiểm tra. Trong trường hợp đó, nó có ý nghĩa để kiểm tra _areSplinesReticulated ở một nơi - phương thức GetSomething công khai - thay vì yêu cầu mỗi lần thực hiện phương thức trừu tượng để thực hiện kiểm tra riêng của nó. Hoặc có thể GetSomething là 90% boilerplate nhưng đòi hỏi một chút logic bổ sung hoặc một phần quan trọng của thông tin mà chỉ có các lớp học có nguồn gốc có thể cung cấp.

Đây là một dạng của mẫu Template Method.

Một GetSomething không ảo nghĩa là mọi lớp dẫn xuất được xử lý chuẩn và chỉ được tham gia thông qua phiên bản DoGetSomething tùy chỉnh của chúng. Nếu GetSomething là ảo, điều đó có nghĩa là các lớp dẫn xuất có thể bỏ qua việc xử lý tiêu chuẩn nếu chúng muốn. Một trong số đó là chiến lược khả thi tùy thuộc vào việc xử lý GetSomething tiêu chuẩn là không thể tách rời với logic lớp (ví dụ: bất biến) hoặc liệu lớp cơ sở muốn cấp tính linh hoạt tối đa cho các lớp dẫn xuất.

0

Tôi đã không nhìn thấy phiên bản bạn mô tả nơi "GetSomething()" là ảo, nhưng tôi đã nhìn thấy (và viết) các lớp học như thế này:

public abstract class Foo 
{ 
    protected abstract void DoBar(); 

    public void Bar() 
    { 
     // do stuff that has to happen regardless of how 
     // DoBar() has been implemented in the derived 
     // class 
     DoBar(); 
     // do other stuff 
    } 
} 

Bởi vì "Bar" không phải là ảo (và tôi cho rằng bạn cũng có thể đóng dấu nó chỉ để chắc chắn) bạn có một cơ hội để "tiêm" mã trước và sau khi "DoBar" phương pháp được gọi là. Nó khá tiện dụng.

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