patterncppModerate
Currency converter using MVC pattern in C++ & QT
Viewed 0 times
convertermvcusingpatterncurrency
Problem
While understanding the MVC pattern, I came across this particular article. I thought to implement it using the C++/QT library.
The intent over here is to implement/use MVC concepts in correct way. Awaiting the feedback/review comments from community.
model.h
model.cpp
view.h
view.cpp
```
#include "view.h"
#include "controller.h"
#include
#include
#include
#include
View::View(QWidget *parent, QString name)
: QWidget(parent), appName(name) {
this->setWindowTitle(appName);
//Create a horizontal container widgets.
hlayout = new QHBoxLayout(this);
hlayout->setSpacing(1);
ruppesinfo = new QLineEdit(this);
ruppesinfo->setPlaceholderText("RuppesInf
The intent over here is to implement/use MVC concepts in correct way. Awaiting the feedback/review comments from community.
model.h
#ifndef MODEL_H
#define MODEL_H
class Model {
public:
Model();
~Model();
double ConvertRuppesIntoDollor(double rs);
double GetDollorValue()const;
double GetRuppeValue() const;
void clear();
private:
double r;
double d;
};
#endif // MODEL_Hmodel.cpp
#include "model.h"
Model::Model(): r(),d() {}
Model::~Model(){}
double Model::ConvertRuppesIntoDollor(double rs) {
r = rs;
d = r/64.0;
return d;
}
double Model::GetDollorValue() const { return d;}
double Model::GetRuppeValue() const { return r;}
void Model::clear() {
r = 0;
d = 0;
}view.h
#ifndef VIEW_H
#define VIEW_H
#include
#include
// Forward Declaration
class QPushButton;
class QLineEdit;
class QHBoxLayout;
class Controller;
class View : public QWidget {
Q_OBJECT
public:
explicit View(QWidget *parent = NULL, QString name = "MVC");
virtual ~View();
void setController(Controller* c);
QString getDollor();
QString getRuppes();
void setDollor(QString d);
void setRuppes(QString r);
public slots:
void ConvertButtonClicked();
void ClearButtonClicked();
private:
QPushButton* press;
QPushButton* clear;
QLineEdit* dollorinfo;
QLineEdit* ruppesinfo;
QHBoxLayout* hlayout;
Controller* controller;
QString appName;
QString dollor;
QString ruppes;
};
#endif // VIEW_Hview.cpp
```
#include "view.h"
#include "controller.h"
#include
#include
#include
#include
View::View(QWidget *parent, QString name)
: QWidget(parent), appName(name) {
this->setWindowTitle(appName);
//Create a horizontal container widgets.
hlayout = new QHBoxLayout(this);
hlayout->setSpacing(1);
ruppesinfo = new QLineEdit(this);
ruppesinfo->setPlaceholderText("RuppesInf
Solution
The typical MVC pattern has a data flow like this:
So data flows from the Model to the View (When State is updated)
So data flows from the View to the Controller (When the user interacts)
So data flows from the Controller to the Model.
Usually how this works.
Note: I am using the generic term Observe here. QT implements this as signals and slots. But that is just an implementation detail.
In a lot of situations there is only one controller per view. So a lot frameworks bundle the View/Controller into a single entity to reduce overhead (but there is no harm in splitting them out).
On the other hand your flow is more like this:
The trouble with this design is that; if you write more code that interacts with the model then the view does not get updated when you change the model.
For example: Say you had ten more currencies.
They are all using the same model. You just have 10 different views on the model to display it in 10 different currencies. Now when you update the model via one control. Only the view associated with that control updates (As it does not know about the other views). What you really want is all the views to register interest in the model. When its state changes they should be notified and update their displays appropriately.
Currently when you add more views the control has to know about each view that could be affected and manually force it to update. This is very error prone.
Now that I have read the article you reference. I see why your code works the way it does. You are following the pattern described. I would hesitate to say that the author if that article is wrong.
See:
https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
As I mentioned above if each control updates the model independently then only the view(s) associated with that particular control will update. Any other V/C that also use the model are not going to update. So every new view that you add you have to go and find every control that updates the model and tell it about the new view so it can tell that view to update as well (this is error prone).
The original pattern is much better. If I add a new view I just register the view as an observer on the model. When the model is updated (by a control) my view is notified and will potentially change its view to reflect the change in the model.
|--->Model -> View -> Controller ----|
| |
|--------------------------------------------|So data flows from the Model to the View (When State is updated)
So data flows from the View to the Controller (When the user interacts)
So data flows from the Controller to the Model.
Usually how this works.
- User updates the view.
- Any control that is interested in the view has registered itself as an observer and thus gets updates notification from the view when the content is changed.
- The control processes the notification and changes the model state.
- Any view that is interested in a model has registered itself as an observer and has gets update notifications when the model changes and can revise the content of the view.
Note: I am using the generic term Observe here. QT implements this as signals and slots. But that is just an implementation detail.
In a lot of situations there is only one controller per view. So a lot frameworks bundle the View/Controller into a single entity to reduce overhead (but there is no harm in splitting them out).
On the other hand your flow is more like this:
(view pulls from model)
Model View -> Controller ----|
^ ^ |
| | |
---------------------------------------|The trouble with this design is that; if you write more code that interacts with the model then the view does not get updated when you change the model.
For example: Say you had ten more currencies.
They are all using the same model. You just have 10 different views on the model to display it in 10 different currencies. Now when you update the model via one control. Only the view associated with that control updates (As it does not know about the other views). What you really want is all the views to register interest in the model. When its state changes they should be notified and update their displays appropriately.
Currently when you add more views the control has to know about each view that could be affected and manually force it to update. This is very error prone.
Now that I have read the article you reference. I see why your code works the way it does. You are following the pattern described. I would hesitate to say that the author if that article is wrong.
See:
https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
As I mentioned above if each control updates the model independently then only the view(s) associated with that particular control will update. Any other V/C that also use the model are not going to update. So every new view that you add you have to go and find every control that updates the model and tell it about the new view so it can tell that view to update as well (this is error prone).
The original pattern is much better. If I add a new view I just register the view as an observer on the model. When the model is updated (by a control) my view is notified and will potentially change its view to reflect the change in the model.
Code Snippets
|--->Model -> View -> Controller ----|
| |
|--------------------------------------------|(view pulls from model)
Model View -> Controller ----|
^ ^ |
| | |
---------------------------------------|Context
StackExchange Code Review Q#99340, answer score: 13
Revisions (0)
No revisions yet.