Có một số lý lẽ tốt cho chống const, ở đây vì vậy đây là quan điểm của tôi: -
Cá nhân, tôi muốn không có những "OnXXXUpdated" như là một phần của các lớp học quản lý của tôi. Tôi nghĩ rằng đây là lý do tại sao có một số nhầm lẫn là để thực hành tốt nhất. Bạn đang thông báo cho các bên quan tâm về điều gì đó và không biết trạng thái của đối tượng có thay đổi trong quá trình thông báo hay không. Hên xui. Điều gì là hiển nhiên đối với tôi, là quá trình thông báo cho các bên quan tâm nên là một const.
Vì vậy, để giải quyết tình trạng khó xử này, đây là những gì tôi sẽ làm gì:
Loại bỏ các chức năng OnXXXXUpdated từ các lớp học quản lý của bạn.
Viết quản lý thông báo, đây là một nguyên mẫu, với các giả định sau:
"args" là một cơ sở hạng tùy ý để thông qua thông tin khi thông báo xảy ra
"Đại biểu" là một số loại của một con trỏ hàm (ví dụ: FastDelegate).
class Args
{
};
class NotificationManager
{
private:
class NotifyEntry
{
private:
std::list<Delegate> m_Delegates;
public:
NotifyEntry(){};
void raise(const Args& _args) const
{
for(std::list<Delegate>::const_iterator cit(m_Delegates.begin());
cit != m_Delegates.end();
++cit)
(*cit)(_args);
};
NotifyEntry& operator += (Delegate _delegate) {m_Delegates.push_back(_delegate); return(*this); };
}; // eo class NotifyEntry
std::map<std::string, NotifyEntry*> m_Entries;
public:
// ctor, dtor, etc....
// methods
void register(const std::string& _name); // register a notification ...
void unRegister(const std::string& _name); // unregister it ...
// Notify interested parties
void notify(const std::string& _name, const Args& _args) const
{
std::map<std::string, NotifyEntry*>::const_iterator cit = m_Entries.find(_name);
if(cit != m_Entries.end())
cit.second->raise(_args);
}; // eo notify
// Tell the manager we're interested in an event
void listenFor(const std::string& _name, Delegate _delegate)
{
std::map<std::string, NotifyEntry*>::const_iterator cit = m_Entries.find(_name);
if(cit != m_Entries.end())
(*cit.second) += _delegate;
}; // eo listenFor
}; // eo class NotifyManager
Tôi đã để lại một số mã như bạn có thể nói, nhưng bạn có ý tưởng. Tôi tưởng tượng rằng Trình quản lý thông báo này sẽ là một singleton. Bây giờ, đảm bảo rằng Manager Thông báo được tạo ra từ rất sớm, phần còn lại của các nhà quản lý của bạn chỉ cần đăng ký thông báo của họ trong constructor của họ như thế này:
MyManager::MyManager()
{
NotificationMananger.getSingleton().register("OnABCUpdated");
NotificationMananger.getSingleton().register("OnXYZUpdated");
};
AnotherManager::AnotherManager()
{
NotificationManager.getSingleton().register("TheFoxIsInTheHenHouse");
};
Bây giờ, khi quản lý của bạn cần phải thông báo cho các bên quan tâm, nó chỉ đơn giản là cuộc gọi thông báo:
MyManager::someFunction()
{
CustomArgs args; // custom arguments derived from Args
NotificationManager::getSingleton().notify("OnABCUpdated", args);
};
Các lớp khác có thể nghe nội dung này.
Tôi đã nhận ra rằng tôi vừa nhập mẫu Observer, nhưng ý định của tôi là cho thấy vấn đề là cách thức những thứ này được nâng lên và liệu chúng có ở trạng thái const hay không. Bằng cách tóm tắt quá trình thông báo ra khỏi lớp mananager, người nhận thông báo được tự do sửa đổi lớp người quản lý đó. Chỉ cần không phải là người quản lý thông báo. Tôi nghĩ điều này là công bằng.
Bên cạnh đó, có một nơi duy nhất để nâng cao thông báo là tốt pracice imho, vì nó cung cấp cho bạn một nơi duy nhất mà bạn có thể theo dõi thông báo của bạn.
Tôi cho rằng bạn đang tranh luận ủng hộ việc khai báo phương pháp const? – starblue
Nếu điều này được đưa ra trong một đánh giá mã, có lẽ tôi sẽ không phản đối một trong hai cách trừ khi có một số yếu tố khác khi chơi. Nếu tất cả mọi người đang truy cập vào toàn cầu và không có tham chiếu const được truyền xung quanh, nó thực sự không quan trọng. Tôi không đồng ý với giả thuyết rằng phân tích tĩnh có thể cho bạn biết nếu phương pháp này là const: Phân tích tĩnh cho bạn biết * có thể * là const * như được triển khai *, nhưng không biết bạn có dự định tăng cường chức năng sau này hay không với số liệu thống kê, hoặc thông điệp xếp hàng hoặc loại bỏ trùng lặp hoặc những gì có bạn). –