【C++設計模式】責任鏈模式
阿新 • • 發佈:2018-12-12
#ifndef __CHAIN_H__ #define __CHAIN_H__ #include <iostream> #include <string> //責任鏈模式:為請求建立一個接受者物件的鏈。這種模式基於請求的型別,對請求的傳送者和接受者進行解耦。屬於行為型模式。 //在這種模式中,通常每個接收者都包含對另一個接收者的引用。如果一個物件不能處理該請求,那麼它會把相同的請求傳給下一個接收者,依此類推。 //責任鏈弱化了發出請求的人和處理請求的人之間的關係,將請求沿著鏈傳遞,讓每個處理者更專注於自己的工作。 //責任鏈模式在實現時,它的鏈的形狀不是職責鏈本身建立和維護的,而是由客戶進行建立的,這就大大提高了責任鏈的靈活性。 //待解決的問題 class Trouble { public: Trouble(int number); int GetNumber(); private: int m_number; }; //處理問題的抽象類 class Support { public: Support(); Support(const std::string & name); Support * SetNext(Support * support); //模板方法 void Proc(Trouble &trouble); //對上層提供介面 virtual int Resolve(Trouble &trouble) = 0; private: std::string m_name; Support * m_next; }; //處理問題編號小於limit值的類 class LimitSupport : public Support { public: LimitSupport(const std::string & name, int limit); virtual int Resolve(Trouble &trouble); private: int m_limit; }; //處理問題編號為基數的類 class OddSupport : public Support { public: OddSupport(const std::string & name); virtual int Resolve(Trouble &trouble); }; //處理問題編號為特定值的類 class SepcialSupport : public Support { public: SepcialSupport(const std::string & name, int number); virtual int Resolve(Trouble &trouble); private: int m_number; }; void TestChain(); #endif
#include "Chain.h" Trouble::Trouble(int number) { m_number = number; } int Trouble::GetNumber() { return m_number; } Support::Support() { } Support::Support(const std::string & name) { this->m_name = name; this->m_next = NULL; } Support * Support::SetNext(Support * support) { this->m_next = support; return this->m_next; } void Support::Proc(Trouble &trouble) { if (Resolve(trouble) == 0) { printf("the %d trouble is resolved by %s\n", trouble.GetNumber(), this->m_name.c_str()); } else if (this->m_next) { this->m_next->Proc(trouble); } else { printf("the %d trouble cannot be resolved\n", trouble.GetNumber()); } } LimitSupport::LimitSupport(const std::string & name, int limit) : Support(name) { this->m_limit = limit; } int LimitSupport::Resolve(Trouble &trouble) { if (trouble.GetNumber() < this->m_limit) { return 0; } return 1; } OddSupport::OddSupport(const std::string & name) : Support(name) { } int OddSupport::Resolve(Trouble &trouble) { if (trouble.GetNumber() % 2 == 1) { return 0; } return 1; } SepcialSupport::SepcialSupport(const std::string & name, int number) : Support(name) { this->m_number = number; } int SepcialSupport::Resolve(Trouble &trouble) { if (trouble.GetNumber() == this->m_number) { return 0; } return 1; } void TestChain() { Support * alice = new LimitSupport("alice", 12); Support * bob = new SepcialSupport("bob", 15); Support * tom = new OddSupport("tom"); alice->SetNext(bob)->SetNext(tom); for (int i=0; i<20; i++) { Trouble trouble(i); alice->Proc(trouble); } return; }