Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Action/logic inside or outside the Windows class?

23 views
Skip to first unread message

JiiPee

unread,
Sep 11, 2019, 6:41:55 AM9/11/19
to
I know this is not Windows programming forum, but because I think this
is more like a C++ expertise question (and not Windows) I ask here.

So lets say I have a window where I show text after some mouse click. A
naive program, but just to keep it simple.
The question is that should I have only windows-related code in the
Window class and create another class dealing
with the logic of the program?

Should all message handler functions forward the call to the program
logic class? So all message handler functions in Window class
should contain normally only 1 line (see example below)?

So which one is better 1) or 2) (ignoring the effiency/style issues...)?
I try to make an example illustrating the two approaches
(GetDocument() returns a document object which contains the text
variable drawMessage_):


1) Mouse logic left in MyWindow class:

class MyWindow
{
public:
    void Draw() {
    // draws GetDocument()->drawMessage_ text on to the window
    }
    void MouseClick(Point mousePosition);
};

void MyWindow::MouseClick(Point mousePosition)
{
    if(mousePosition.x > 150)
    {
        GetDocument()->drawMessage_ = "Mouse crossed the border";
        Draw();
    }
}

========================================================================

2) Mouse logic done in MyWindowLogic class:

class MyWindowLogic
{
public:
    void Draw() {
    // draws GetDocument()->drawMessage_ text on to the window
    }
    void HandleMouseClick(Point mousePosition);
};

void MyWindowLogic::HandleMouseClick(Point mousePosition)
{
    if(mousePosition.x > 150)
    {
        drawMessage_ = "Mouse crossed the border";
        Draw();
    }
}

///////////////////////////

class MyWindow
{
public:
    void Draw() {
        logic.Draw(); // forward all action to the logic class
    }
    void MouseClick(Point mousePosition);

private:
    MyWindowLogic logic;
};

void MyWindow::MouseClick(Point mousePosition)
{
    logic.HandleMouseClick(mousePosition); // do all action in logic class
}

###########

If it an overkill to create a new class for this rather than place all
code in the MyWindow class?
Should we keep things "simple" here and place all such code in the
MyWindow class?

Or this kind of separation of logic/windows code is good?

Öö Tiib

unread,
Sep 11, 2019, 9:45:27 AM9/11/19
to
On Wednesday, 11 September 2019 13:41:55 UTC+3, JiiPee wrote:
> So lets say I have a window where I show text after some mouse click. A
> naive program, but just to keep it simple.

All actual software follows input-process-output (IPO) model.

> The question is that should I have only windows-related code in the
> Window class and create another class dealing
> with the logic of the program?

GUI code is often made to deal with human operator's input and output
and only with it. Then they do not put into GUI classes any code that
a) inputs from any other sources
b) processes the data that was acquired from any sources
c) or outputs its results to any other targets
and basically ... that is it.
Since your example task lacked responsibilities to do anything
of those a), b) or c) it is bad example how to split responsibilities
that way. Note that those a), b) and c) are usually called "program
logic" by such split.

JiiPee

unread,
Sep 11, 2019, 10:28:31 AM9/11/19
to
On 11/09/2019 14:45, Öö Tiib wrote:
> On Wednesday, 11 September 2019 13:41:55 UTC+3, JiiPee wrote:
> The question is that should I have only windows-related code in the
>> Window class and create another class dealing
>> with the logic of the program?
> GUI code is often made to deal with human operator's input and output
> and only with it. Then they do not put into GUI classes any code that
> a) inputs from any other sources
> b) processes the data that was acquired from any sources
> c) or outputs its results to any other targets


Thanks


Can you give 1-2 examples pls? Does for example b) mean that processing
for example database issues:

void MyWindow::MouseClick(Point mousePosition)
{
    if(mousePosition.x > 150)
    {
        // -open database

        // -add line into database

        Draw();
    }
}


should not be done like that in MyWindow class? because database is an
outside source?


> and basically ... that is it.
> Since your example task lacked responsibilities to do anything
> of those a), b) or c) it is bad example how to split responsibilities
> that way.


but it answer the question that mouse related code can be done in
MyWindow, I understand. This is a real world example, because

I process mouse input in my message handlers.


> Note that those a), b) and c) are usually called "program
> logic" by such split.
>


ok, so in my example program you would prefer:

void MyWindow::MouseClick(Point mousePosition)
{
    if(mousePosition.x > 150)
    {
        GetDocument()->drawMessage_ = "Mouse crossed the border";
        Draw();
    }
}


so checking/processing the mouse values in MyWindow class function.

JiiPee

unread,
Sep 11, 2019, 10:46:05 AM9/11/19
to
On 11/09/2019 14:45, Öö Tiib wrote:
> On Wednesday, 11 September 2019 13:41:55 UTC+3, JiiPee wrote:
> GUI code is often made to deal with human operator's input and output
> and only with it. Then they do not put into GUI classes any code that
> a) inputs from any other sources
> b) processes the data that was acquired from any sources
> c) or outputs its results to any other targets
> and basically ... that is it.


Is there any web site teaching this I could read about it?

JiiPee

unread,
Sep 11, 2019, 10:53:25 AM9/11/19
to
On 11/09/2019 14:45, Öö Tiib wrote:
> GUI code is often made to deal with human operator's input and output
> and only with it. Then they do not put into GUI classes any code that
> a) inputs from any other sources
> b) processes the data that was acquired from any sources
> c) or outputs its results to any other targets
> and basically ... that is it.
> Since your example task lacked responsibilities to do anything
> of those a), b) or c) it is bad example how to split responsibilities
> that way. Note that those a), b) and c) are usually called "program
> logic" by such split.


In my real application I have OpenGL code in the View (Windows) class.
So I am thinking that should all this data/functionality relating to
opengl part of the program logic be left in the View or I should move
all those member variables to ProgramLogic class?

Like drawing the coordinate axis...should I place that variable m_axis
(doing the coordinate axis) inside my View class and also put its logic
in View class (moving/updating and rotating it)? Or move m_axis to
ProgramLogic class and do its functionality there?


>


JiiPee

unread,
Sep 11, 2019, 10:58:53 AM9/11/19
to
On 11/09/2019 15:53, JiiPee wrote:
>
> In my real application I have OpenGL code in the View (Windows) class.
> So I am thinking that should all this data/functionality relating to
> opengl part of the program logic be left in the View or I should move
> all those member variables to ProgramLogic class?


I know there is no clear answer, but just asking if this "might" be a
good solution or possibility.


Paavo Helde

unread,
Sep 11, 2019, 11:22:33 AM9/11/19
to
On 11.09.2019 13:41, JiiPee wrote:
> I know this is not Windows programming forum, but because I think this
> is more like a C++ expertise question (and not Windows) I ask here.
>
> So lets say I have a window where I show text after some mouse click. A
> naive program, but just to keep it simple.
> The question is that should I have only windows-related code in the
> Window class and create another class dealing
> with the logic of the program?

In general, yes, in the Window class you should have only
windows-related logic.

Another way to think about that is that you want to put all your program
logic under unit tests control anyway. Simulating mouse clicks for unit
testing might not be so simple and would mix up testing the GUI and the
program logic, so most of the program should be testable without GUI.

So ideally you should first write your program logic classes together
with unit tests. Once the functionality is working and the tests are
passing, only then start adding windows related classes to expose this
functionality in GUI. Refactor, rinse and repeat as needed, unit tests
are now there and holding the functionality intact.

JiiPee

unread,
Sep 11, 2019, 11:45:13 AM9/11/19
to
Did I understand correctly that you prefer something like 2)? that the
mouse action code is not in the Windows class at all?

Yes, I agree that for testing purposes its beneficial its separated, as
testing Windows class would be difficult :).

Paavo Helde

unread,
Sep 11, 2019, 12:12:30 PM9/11/19
to
No, in your example you just forwarded some GUI related logic to another
class, for no obvious reason. GUI logic should remain in the GUI
classes. In general, the program logic classes should not contain word
"mouse" or "click".

If you click a mouse "out of the border", this might affect the program
logic or not. Maybe you want to call PauseCalculation() on your app, for
example. If there really is no other effect than changing a message
string, then the mouse click function should call
logic.SetStatusMessage("...") or something like that.

Of course, borders are fuzzy here. YMMV.



JiiPee

unread,
Sep 11, 2019, 12:51:58 PM9/11/19
to
On 11/09/2019 17:12, Paavo Helde wrote:
> No, in your example you just forwarded some GUI related logic to
> another class, for no obvious reason. GUI logic should remain in the
> GUI classes. In general, the program logic classes should not contain
> word "mouse" or "click".
>
> If you click a mouse "out of the border", this might affect the
> program logic or not. Maybe you want to call PauseCalculation() on
> your app, for example. If there really is no other effect than
> changing a message string, then the mouse click function should call
> logic.SetStatusMessage("...") or something like that.


ok, so something like this:

void MyWindow::MouseClick(Point mousePosition)
{
    if(mousePosition.x > 150)
    {
        logic.SetStatusMessage("...");
    }
}


So you would leave the mouse condition check there ( if(mousePosition.x
> 150)   ), but the action related to it would go to logic class?

red floyd

unread,
Sep 11, 2019, 12:57:25 PM9/11/19
to
Yes. Mouse position is related to the GUI.

There are a couple of paradigms related to this sort of thing:
* Model/View/Controller (MVC), where you classes representing the
data model, the view (GUI), and the controller (program logic)
* Document/View (used by MFC), where you have a view class (the GUI,
or in your case MyWindow), and the "Document" class, which contains
both the data model and the controlling logic.


Paavo Helde

unread,
Sep 11, 2019, 1:24:19 PM9/11/19
to
Yes, exactly.





JiiPee

unread,
Sep 11, 2019, 2:42:20 PM9/11/19
to
ok thanks. Good to hear others points.


>
>
>
>

JiiPee

unread,
Sep 11, 2019, 2:43:00 PM9/11/19
to
On 11/09/2019 17:56, red floyd wrote:
> On 9/11/2019 9:51 AM, JiiPee wrote:
>> On 11/09/2019 17:12, Paavo Helde wrote:
>>> No, in your example you just forwarded some GUI related logic to
>>> another class, for no obvious reason. GUI logic should remain in the
>>> GUI classes. In general, the program logic classes should not
>>> contain word "mouse" or "click".
>>>
>>> If you click a mouse "out of the border", this might affect the
>>> program logic or not. Maybe you want to call PauseCalculation() on
>>> your app, for example. If there really is no other effect than
>>> changing a message string, then the mouse click function should call
>>> logic.SetStatusMessage("...") or something like that.
>>
>>
>> ok, so something like this:
>>
>> void MyWindow::MouseClick(Point mousePosition)
>> {
>>      if(mousePosition.x > 150)
>>      {
>>          logic.SetStatusMessage("...");
>>      }
>> }
>>
>>
>> So you would leave the mouse condition check there (
>> if(mousePosition.x  > 150)   ), but the action related to it would go
>> to logic class?
>>
>
> Yes.  Mouse position is related to the GUI.


thanks, good to get confirmation


>
> There are a couple of paradigms related to this sort of thing:
> * Model/View/Controller (MVC), where you classes representing the
>   data model, the view (GUI), and the controller (program logic)
> * Document/View (used by MFC), where you have a view class (the GUI,
>   or in your case MyWindow), and the "Document" class, which contains
>   both the data model and the controlling logic.
>

yes I use MFC, since 1996 :)



Öö Tiib

unread,
Sep 12, 2019, 4:05:58 AM9/12/19
to
On Wednesday, 11 September 2019 17:28:31 UTC+3, JiiPee wrote:
> On 11/09/2019 14:45, Öö Tiib wrote:
> > On Wednesday, 11 September 2019 13:41:55 UTC+3, JiiPee wrote:
> > The question is that should I have only windows-related code in the
> >> Window class and create another class dealing
> >> with the logic of the program?
> > GUI code is often made to deal with human operator's input and output
> > and only with it. Then they do not put into GUI classes any code that
> > a) inputs from any other sources
> > b) processes the data that was acquired from any sources
> > c) or outputs its results to any other targets
>
>
> Thanks
>
>
> Can you give 1-2 examples pls?

It is tricky to give examples of all those architectural
patterns how to separate "presentation layer" of software from other
layers (like "service layer", "business logic layer", "persistence layer").
There are tons of materials to read about various takes on it like
"model-view-adapter", "presentation-action-control" or
"model-view-viewmodel".

> Does for example b) mean that processing
> for example database issues:
>
> void MyWindow::MouseClick(Point mousePosition)
> {
>     if(mousePosition.x > 150)
>     {
>         // -open database
>
>         // -add line into database
>
>         Draw();
>     }
> }
>
>
> should not be done like that in MyWindow class? because database is an
> outside source?

Yes.

> > and basically ... that is it.
> > Since your example task lacked responsibilities to do anything
> > of those a), b) or c) it is bad example how to split responsibilities
> > that way.
>
>
> but it answer the question that mouse related code can be done in
> MyWindow, I understand. This is a real world example, because
>
> I process mouse input in my message handlers.

For rest of application there should be no such thing as
"mouse", "window" or "keyboard". Application should have
purpose.

> > Note that those a), b) and c) are usually called "program
> > logic" by such split.
> >
>
>
> ok, so in my example program you would prefer:
>
> void MyWindow::MouseClick(Point mousePosition)
> {
>     if(mousePosition.x > 150)
>     {
>         GetDocument()->drawMessage_ = "Mouse crossed the border";
>         Draw();
>     }
> }
>
>
> so checking/processing the mouse values in MyWindow class function.

It is hard to explain since that MyWindow should have meaning,
the line where x is 150 should have meaning and clicking should
be meaningful gesture. Your examples lack any meaning whatsoever
so those can't be used for discussing what you want to discuss.
Better take something that has meaning, even if the meaning is
absurdly simple, for example how to separate tic-tac-toe game
and GUI for it.

0 new messages