|
Prev: Modularity problems with multiple dispatch (was: Scala and problems with OOP)
Next: Can you suggest a project?
From: Firkraag on 12 Nov 2007 16:28 #include <iostream> #include <string> #include <algorithm> #include <functional> #include <list> struct IObserver { virtual ~IObserver(){} virtual void update() = 0; }; struct IObservable { virtual ~IObservable(){} virtual void registerObserver(IObserver& o) = 0; virtual void removeObserver(IObserver& o) = 0; virtual void notifyObservers() const = 0; }; struct IModel : IObservable { virtual ~IModel(){} virtual void set(int n) = 0; virtual void add(int n) = 0; virtual void sub(int n) = 0; virtual int get() const = 0; }; class Model : public IModel { public: Model() : x(0) {} Model(int n) : x(n) {} virtual void set(int n) { x = n; notifyObservers(); } virtual void add(int n) { set(get() + n); } virtual void sub(int n) { set(get() - n); } virtual int get() const { return x; } virtual void registerObserver(IObserver& o) { container.push_back(&o); } virtual void removeObserver(IObserver& o) { container.remove(&o); } virtual void notifyObservers() const { for_each(container.begin(), container.end(), std::mem_fun(&IObserver::update)); } private: int x; typedef std::list<IObserver*> container_t; container_t container; }; struct IController; class View : public IObserver { public: // num (just a displayed number of the view to indicate "different views" View(Model& mo, IController& ico, int num = 1) : m(&mo), ic(&ico), n(num) { m->registerObserver(*this); } void displayView() { std::cout << "View " << n << " "; } void hello() { std::cout << "Hello\n"; } void bye() { std::cout << "Bye\n"; } void promptMsg() { std::cout << "Enter a number: "; } virtual void update() { displayView(); std::cout << m->get() << '\n'; } private: Model* m; IController* ic; int n; }; struct IController { virtual ~IController(){} virtual void onOffSwitch() = 0; virtual void set() = 0; virtual void add() = 0; virtual void sub() = 0; }; class Controller : public IController { public: Controller(Model& mo) : m(&mo), v(0), isRunning(false) { v = new View(mo, *this); } virtual void onOffSwitch() { isRunning ^= true; isRunning ? v->hello() : v->bye(); } ~Controller() { delete v; v = 0; } virtual void set() { if(!isRunning) return; v->promptMsg(); m->set(this->input()); } void add() { if(!isRunning) return; v->promptMsg(); m->add(this->input()); } void sub() { if(!isRunning) return; v->promptMsg(); m->sub(this->input()); } private: Model* m; View* v; bool isRunning; int input() { int n; std::cin >> n; return n; } Controller(Controller const&); Controller& operator=(Controller const&); }; int main() { Model m; Controller c(m); View view2(m, c, 2); // 2 is the displayed 2nd view's nr. c.onOffSwitch(); c.set(); c.add(); c.sub(); c.onOffSwitch(); } Am I doing it right? My question is also about the methods like hello() and bye(). should they be a part of of the view? I was told that view should be concerned only about "visualisation" of the model and about itself. I wonder if hello() and bye() should belong to the view or rather to the controller? Thank you in advance.
From: Daniel T. on 12 Nov 2007 20:28
Firkraag <firkraag07(a)tlen.pl> wrote: [snipped code] > Am I doing it right? It's hard to tell, the solution is way more complicated than the problem requires. :-) It seems to me that IObserverable and IModel serve no purpose and can be removed. > My question is also about the methods like hello() and bye(). > should they be a part of of the view? I was told that view should > be concerned only about "visualisation" of the model and about > itself. I wonder if hello() and bye() should belong to the view or > rather to the controller? I'd say hello() and bye() are in the right place. I think of it as the View is in charge of output while the controller is in charge of input. The hard part here is that MVC is specifically for mode-less systems, but the console is model. |