2012-11-13 40 views
8

Tôi đang viết một số mã xử lý tin nhắn, theo đó mỗi thông báo là cấu trúc POD. Trên đường đi của văn bản này sẽ được xác định một lớp cơ sở trừu tượng, với functiosn ảo đối với từng loại thông điệp ví dụ:Ý nghĩa của việc sử dụng mpl :: inherit_linearly để xác định giao diện

class AbstractHandler 
{ 
public: 
    virtual void handleMessage(const MessageType1& msg) =0; 
    virtual void handleMessage(const MessageType2& msg) =0; 
    virtual void handleMessage(const MessageType3& msg) =0; 
    virtual void handleMessage(const MessageType4& msg) =0; 
}; 

Và lớp bê tông sau đó tạo ra nguồn gốc mà thực hiện các chức năng xử lý:

class ConcreteHandler : public AbstractHandler 
{ 
public: 
    virtual void handleMessage(const MessageType1& msg); 
    virtual void handleMessage(const MessageType2& msg); 
    virtual void handleMessage(const MessageType3& msg); 
    virtual void handleMessage(const MessageType4& msg); 
}; 

Nếu tin nhắn mới được thêm vào hệ thống AbstractHandler phải được cập nhật cùng với tất cả các loại có nguồn gốc.

Hoặc tôi có thể giữ tất cả các loại tin nhắn được hỗ trợ trong một chuỗi mpl và sử dụng mpl::inherit_linearly để tạo lớp cơ sở trừu tượng.

(Lưu ý: Tôi đã sử dụng một mpl::vector của các loại tin nhắn khác trong các mã.)

ví dụ: xử lý

typedef mpl::vector< MessageType1, MessageType2, 
        MessageType3, MessageType4 > message_types; 

template< class Message > 
class Wrapper 
{ 
public: 
    virtual void handleMessage(const Message& msg) = 0; 
protected: 
    ~Wrapper(){} 
}; 

class AbstractHandler 
    : public mpl::inherit_linearly< message_types 
            , mpl::inherit< mpl_1, Wrapper<mpl::_2> > 
            >::type 
{ 
public: 
    virtual ~AbstractHandler() {} 
}; 

bê tông sau đó xuất phát từ AbstractHandler. Điều này có nghĩa là bất cứ khi nào các kiểu tin nhắn mới được thêm vào hệ thống, nó chỉ đơn giản là một trường hợp thay đổi trình tự mpl::vector<types...> message_types, thêm các hàm mới handleMessage vào các lớp dẫn xuất.

Theo tôi điều này làm giảm bảo trì dài hạn, kể từ khi AbstractHandler sẽ tự động có chức năng ảo tinh khiết cho tất cả thư trong mpl::vector message_types

Xét về hiệu suất là có bất kỳ nhược điểm để sử dụng phương pháp này?

Ý nghĩa của việc sử dụng mpl::inherit_linearly để tạo các lớp cơ sở trừu tượng là gì?

Trả lời

3

Tôi đã thực hiện mã tương tự trước đây (và tôi đang làm lại ngày hôm nay).

Không có chi phí ngoài chi phí do thừa kế. Chủ yếu là vì loại cuối cùng được xác định tại thời gian biên dịch, không phải thời gian chạy.

Tuy nhiên, điều này rõ ràng có thể làm cho thời gian biên dịch của bạn dài hơn, so với kích thước danh sách loại thư. Nếu như tôi bạn cũng viết một lớp điều phối thư (có thể lấy bất cứ thứ gì để gửi đến bất kỳ trình xử lý nào cho loại này), thì có thể tốn kém vào thời gian biên dịch.

Nếu không, sẽ tốt.

Chỉ cần hiểu ý nghĩa của loại thiết lập này: danh sách các thư được xử lý được xác định tại thời gian biên dịch, không phải thời gian chạy. Một số hệ thống sự kiện là thời gian chạy vì các yêu cầu sử dụng. Vì vậy, hãy chắc chắn rằng đó là những gì bạn muốn trong trường hợp sử dụng của bạn.

+0

cảm ơn đã xác nhận suy nghĩ của tôi về điều này. Bây giờ tôi có một giải pháp làm việc là một phần của API mà các dịch vụ khách hàng sử dụng khi xử lý thư. Cho đến nay tất cả người dùng như API ... MPL chắc chắn giúp tạo ra mã mạnh mẽ ... – mark

+0

Về phía người dùng, nó có một số nhược điểm mặc dù: nó ít rõ ràng hơn những chức năng nào cần được xác định. Một trình biên dịch (gần đây) tốt sẽ tạo ra một thông điệp rõ ràng vì vậy tôi đoán nó là ok. Nó cũng sẽ tốt hơn nếu có một cách để buộc người dùng ghi đè rõ ràng các chức năng (để đảm bảo rằng họ không phạm sai lầm). – Klaim

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