Designing lower level classes.

Discussion in 'C++' started by Gunter Schelfhout, Jun 29, 2008.

  1. I'm starting to write a QT-program on Linux but I'm not very experienced
    yet. (hang on, it will be on topic)
    What is the best way to go to design the lower level classes?
    Should I use the standard libraries as much as possible so I can reuse the
    classes maybe in the future in non-GUI programs?
    Or is it best to use as much of the QT-libraries from the beginning?
    For example string <-> QString.
     
    Gunter Schelfhout, Jun 29, 2008
    #1
    1. Advertising

  2. On 2008-06-29 14:15, Gunter Schelfhout wrote:
    > I'm starting to write a QT-program on Linux but I'm not very experienced
    > yet. (hang on, it will be on topic)
    > What is the best way to go to design the lower level classes?
    > Should I use the standard libraries as much as possible so I can reuse the
    > classes maybe in the future in non-GUI programs?
    > Or is it best to use as much of the QT-libraries from the beginning?
    > For example string <-> QString.


    My advice, for any non-trivial application, is to divide the code into
    (at least) two parts: one for the "business" logic and one for
    interfacing with the application (be it a GUI, command line, or
    something else). In the business logic part I would advice against using
    more dependencies than necessary to keep the code as portable as
    possible, but if a specific library does exactly what you need then use
    it. You might also consider putting the lower layers in one or more
    libraries which makes it even easier to change to GUI later on.

    --
    Erik Wikström
     
    Erik Wikström, Jun 29, 2008
    #2
    1. Advertising

  3. Gunter Schelfhout wrote:
    > I'm starting to write a QT-program on Linux but I'm not very experienced
    > yet. (hang on, it will be on topic)
    > What is the best way to go to design the lower level classes?
    > Should I use the standard libraries as much as possible so I can reuse the
    > classes maybe in the future in non-GUI programs?
    > Or is it best to use as much of the QT-libraries from the beginning?
    > For example string <-> QString.


    My personal experience on using GUI libraries is that you should,
    obviously, separate what all the functionalities of the program which
    you can into their own portable modules (this is rather obvious for the
    simple reason that it's good OOD), but trying to abstract away the
    non-standard GUI library completely from your program is usually more
    trouble than it's worth.

    I once tried this, and the results were less than satisfactory. My
    intention was to make a clean abstraction of the underlying GUI library,
    ie. hide everything in it inside its own module in a way that would
    allow me to change the underlying GUI library easily to something else
    (eg. from gtk to wxwidgets or to qt or to native Windows API or whatever).

    While this sounds like a great idea in theory (and it still is), in
    practice the whole system became awkward, limited and hard to maintain
    and expand. At one point I simply noticed that I was basically
    replicating the underlying GUI public interface in my own "abstract"
    module. While I got something working, in the end I was not very
    satisfied with the result. (And, rather ironically, the underlying GUI
    library was never changed to anything else, so all that abstracting
    basically went to waste.)

    Sure, liberally using the GUI library everywhere in your code will tie
    your code to that library in question, but whether that's better or
    worse than the alternative is not clear at all. In some cases a clever
    design could allow a clean abstraction between your code and the
    library, but it's not easy.
     
    Juha Nieminen, Jun 29, 2008
    #3
  4. Juha Nieminen wrote:

    [snip]

    >
    > Sure, liberally using the GUI library everywhere in your code will tie
    > your code to that library in question, but whether that's better or
    > worse than the alternative is not clear at all. In some cases a clever
    > design could allow a clean abstraction between your code and the
    > library, but it's not easy.



    I'm sure I'm not the only beginner facing this question and the most books
    handle the technicalities of the language well but don't give any info like
    this.
    Probably this info will be in other more general progamming books I suppose?
    I noticed the book 'Large scale programs with C++' or something from Addison
    Wesley. I will look for a review. Maybe this is just the book I need for
    questions like this.

    Anyway, thanks a lot. It gives me something to think about.
     
    Gunter Schelfhout, Jun 29, 2008
    #4
  5. Gunter Schelfhout

    Stefan Ram Guest

    Juha Nieminen <> writes:
    >simple reason that it's good OOD), but trying to abstract away the
    >non-standard GUI library completely from your program is usually more


    This usually will not work, because the GUI library often uses
    callbacks or acts as a framework and by this it enforces a
    specific structure of the high level code of the application,
    and different GUI libraries indeed have different APIs,
    because.

    Separation still is possible, but just the other way around:
    You abstract away every part of your program that is not
    directly related to the user interface - but »abstract« now
    is the wrong verb: You stash it away in a »model« and a
    non-UI-related library to the maximum extend possible.

    What is left over is a program that solely consists of UI
    related parts (view and controller). This might be a text
    console UI or a GUI. Now, this UI needs to be written for
    every type of UI library used: For example, once for a console
    library, once for GTK, once for WxWidgets, and so on. It is
    the rest that cannot be abstract from the UI, because
    everything else already has been stashed away in the model or
    a non-UI-related library.

    What is won by this approach is that the code for the model
    and in the non-UI-related library does not have to be changed,
    when writing the controller and view for a annother UI.
     
    Stefan Ram, Jun 29, 2008
    #5
  6. On 2008-06-29 16:43, Stefan Ram wrote:
    > Juha Nieminen <> writes:
    >>simple reason that it's good OOD), but trying to abstract away the
    >>non-standard GUI library completely from your program is usually more

    >
    > This usually will not work, because the GUI library often uses
    > callbacks or acts as a framework and by this it enforces a
    > specific structure of the high level code of the application,
    > and different GUI libraries indeed have different APIs,
    > because.
    >
    > Separation still is possible, but just the other way around:
    > You abstract away every part of your program that is not
    > directly related to the user interface - but »abstract« now
    > is the wrong verb: You stash it away in a »model« and a
    > non-UI-related library to the maximum extend possible.
    >
    > What is left over is a program that solely consists of UI
    > related parts (view and controller). This might be a text
    > console UI or a GUI. Now, this UI needs to be written for
    > every type of UI library used: For example, once for a console
    > library, once for GTK, once for WxWidgets, and so on. It is
    > the rest that cannot be abstract from the UI, because
    > everything else already has been stashed away in the model or
    > a non-UI-related library.
    >
    > What is won by this approach is that the code for the model
    > and in the non-UI-related library does not have to be changed,
    > when writing the controller and view for a annother UI.


    And if you ever want to incorporate the functionality of the application
    in some other, bigger, application you just have to include the module/
    link to the library. Even better, if you do create a separate library
    and use a pure C interface, you can often use the module from other
    programming languages.

    --
    Erik Wikström
     
    Erik Wikström, Jun 29, 2008
    #6
  7. Stefan Ram wrote:

    [snip]

    >
    > What is won by this approach is that the code for the model
    > and in the non-UI-related library does not have to be changed,
    > when writing the controller and view for a annother UI.


    Ok, since I am still in the design phase, it's probably better to keep
    things separated as much as I can.
    I'm glad I asked because on the IRC-channel of qt, people advised the
    complete opposite.

    Somebody who has good books of software design in his library which are
    worth reading?
     
    Gunter Schelfhout, Jun 29, 2008
    #7
  8. Stefan Ram wrote:
    > Separation still is possible, but just the other way around:
    > You abstract away every part of your program that is not
    > directly related to the user interface - but »abstract« now
    > is the wrong verb: You stash it away in a »model« and a
    > non-UI-related library to the maximum extend possible.


    This is a good design, but possible (or, more precisely, feasible)
    only if the core code of your program is not heavily dependent on the
    GUI itself.

    I have used this design myself many times. The typical situation is a
    program which reads some input data, performs some lengthy and heavy
    calculations/processing on it, and outputs the results to a file. The
    core implementation (including I/O and the calculations) is easy to put
    into its own separate module, and then it's easy to create a
    command-line interface as well as a GUI application (using whichever
    library) which uses this module in question. (Perhaps the thing which
    needs the most careful design is how to pass the user-defined options
    from the UI to the module.)

    However, not all programs are like that. Many programs require, for
    example, user input in real-time (such as mouse and keyboard events),
    drawing things on screen, update some GUI elements (such as the value of
    some spinbutton) and other such GUI-dependent functionalities. This is
    where abstracting the core code from the GUI becomes laborious, if not
    outright unfeasible.
     
    Juha Nieminen, Jun 29, 2008
    #8
  9. Gunter Schelfhout

    Stefan Ram Guest

    Gunter Schelfhout <> writes:
    >Ok, since I am still in the design phase, it's probably better to keep
    >things separated as much as I can.


    It is not even required to keep it separated right from the
    start.

    You also can have some »dirty« code parts in the first version
    where data processing and UI interface code is mixed and
    refactor it later to get the separation. Not everyone is so
    perfect that he can write it all separated from the start.

    Between sessions of coding to extend the set of features,
    there always should be sessions to improve the quality of the
    code without adding new features. Nobody can write everything
    in the best possible way the first time. But one will
    eventually not be able to maintain the code anymore if one
    never refactors it to improve separation of responsibilities.
     
    Stefan Ram, Jun 29, 2008
    #9
  10. Stefan Ram wrote:

    > Gunter Schelfhout <> writes:
    >>Ok, since I am still in the design phase, it's probably better to keep
    >>things separated as much as I can.

    >
    > It is not even required to keep it separated right from the
    > start.
    >
    > You also can have some »dirty« code parts in the first version
    > where data processing and UI interface code is mixed and
    > refactor it later to get the separation. Not everyone is so
    > perfect that he can write it all separated from the start.
    >
    > Between sessions of coding to extend the set of features,
    > there always should be sessions to improve the quality of the
    > code without adding new features. Nobody can write everything
    > in the best possible way the first time. But one will
    > eventually not be able to maintain the code anymore if one
    > never refactors it to improve separation of responsibilities.


    I agree, but this is imho one of the decisions which are almost impossible
    to switch back later on since a complete refacturing is then needed which
    I'm trying to avoid.
    So it's probably advisable to keep the the core classes as much as possible
    independant of the GUI (and there libraries) and if nescessary, to provide
    an extra layer to glue the core with the GUI.

    I found out that between learning the technicalities and writing a program,
    there is al lot more to discover. ;-)
     
    Gunter Schelfhout, Jun 29, 2008
    #10
  11. On 2008-06-29 17:45, Stefan Ram wrote:
    > Gunter Schelfhout <> writes:
    >>Ok, since I am still in the design phase, it's probably better to keep
    >>things separated as much as I can.

    >
    > It is not even required to keep it separated right from the
    > start.
    >
    > You also can have some »dirty« code parts in the first version
    > where data processing and UI interface code is mixed and
    > refactor it later to get the separation. Not everyone is so
    > perfect that he can write it all separated from the start.
    >
    > Between sessions of coding to extend the set of features,
    > there always should be sessions to improve the quality of the
    > code without adding new features. Nobody can write everything
    > in the best possible way the first time. But one will
    > eventually not be able to maintain the code anymore if one
    > never refactors it to improve separation of responsibilities.


    I disagree, for the same reason. Nobody is perfect and once things work
    it is all to easy to not refactor the code just to get a better design.
    Write code with good separation from the beginning and then refactor the
    interfaces between modules if needed. Also, this way you will keep the
    "dirty" pieces of code well contained from other modules and you can
    focus on one module at a time.

    While I do agree that you should stop developing every once in a while
    and take some time to clean up the code it might not always be possible
    (while it is short-sighted many companies do not care about refactoring
    until they absolutely have to). I believe in trying to get as good
    design as possible from the beginning, since it (usually) keeps down the
    decay-rate of the code. Of course, if you have good processes then it is
    less of a problem.

    --
    Erik Wikström
     
    Erik Wikström, Jun 29, 2008
    #11
  12. On 2008-06-29 17:38, Juha Nieminen wrote:
    > Stefan Ram wrote:
    >> Separation still is possible, but just the other way around:
    >> You abstract away every part of your program that is not
    >> directly related to the user interface - but »abstract« now
    >> is the wrong verb: You stash it away in a »model« and a
    >> non-UI-related library to the maximum extend possible.

    >
    > This is a good design, but possible (or, more precisely, feasible)
    > only if the core code of your program is not heavily dependent on the
    > GUI itself.
    >
    > I have used this design myself many times. The typical situation is a
    > program which reads some input data, performs some lengthy and heavy
    > calculations/processing on it, and outputs the results to a file. The
    > core implementation (including I/O and the calculations) is easy to put
    > into its own separate module, and then it's easy to create a
    > command-line interface as well as a GUI application (using whichever
    > library) which uses this module in question. (Perhaps the thing which
    > needs the most careful design is how to pass the user-defined options
    > from the UI to the module.)
    >
    > However, not all programs are like that. Many programs require, for
    > example, user input in real-time (such as mouse and keyboard events),
    > drawing things on screen, update some GUI elements (such as the value of
    > some spinbutton) and other such GUI-dependent functionalities. This is
    > where abstracting the core code from the GUI becomes laborious, if not
    > outright unfeasible.


    On the other hand, in these kinds of applications the GUI code is
    usually a very large percentage of the whole application, if you ever
    want to change GUI framework it will take a lot of work regardless of
    how abstract your logic code is. When creating those kinds of
    applications you really do not want to select the wrong framework,
    because you'll gonna have to live with it for a long time.

    --
    Erik Wikström
     
    Erik Wikström, Jun 29, 2008
    #12
  13. Gunter Schelfhout

    Stefan Ram Guest

    Juha Nieminen <> writes:
    >However, not all programs are like that. Many programs require, for
    >example, user input in real-time (such as mouse and keyboard events),
    >drawing things on screen, update some GUI elements (such as the value of
    >some spinbutton) and other such GUI-dependent functionalities. This is
    >where abstracting the core code from the GUI becomes laborious, if not
    >outright unfeasible.


    In this case, the UI-dependent part of the program is large
    and the UI-independent part of the program is small or missing.
    Sometimes it happens to be this way, and then a port to another
    GUI library will nearly be a complete rewrite. I do not see
    any other solution for this case than to live (cope) with it.

    A indication of such a type of program might be that it can
    not be ported to some kinds of environment at all. For example,
    when the definition of a program includes »drawing with the
    mouse«, it will not be possible to port it to a keyboard
    interface by its definition.
     
    Stefan Ram, Jun 29, 2008
    #13
  14. Gunter Schelfhout

    James Kanze Guest

    On Jun 29, 6:04 pm, -berlin.de (Stefan Ram) wrote:
    > Juha Nieminen <> writes:
    > >However, not all programs are like that. Many programs
    > >require, for example, user input in real-time (such as mouse
    > >and keyboard events), drawing things on screen, update some
    > >GUI elements (such as the value of some spinbutton) and other
    > >such GUI-dependent functionalities. This is where abstracting
    > >the core code from the GUI becomes laborious, if not outright
    > >unfeasible.


    > In this case, the UI-dependent part of the program is large
    > and the UI-independent part of the program is small or missing.
    > Sometimes it happens to be this way, and then a port to another
    > GUI library will nearly be a complete rewrite. I do not see
    > any other solution for this case than to live (cope) with it.


    > A indication of such a type of program might be that it can
    > not be ported to some kinds of environment at all. For example,
    > when the definition of a program includes »drawing with the
    > mouse«, it will not be possible to port it to a keyboard
    > interface by its definition.


    This sounds like the old lightweight client vs. heavyweight
    client dicotomy. Looking at the larger picture: at least in
    business applications (but also in some of the process control
    work I've done as well), there is a large body of "business
    logic" (or application logic, if the application isn't
    business), which can (and definitely should) be completely
    separated from the GUI. In the lightweight client model, it is
    so completely separated that it runs in a different program,
    often on a different system. In which case, of course, the
    client is almost pure GUI.

    Regardless of where it is located, I would keep this business
    logic completely separate from the GUI. In most cases, the GUI
    itself will use some variant of MVC, in which the "model" serves
    as a bridge between the GUI and the business logic (and doesn't
    implement any of the business logic itself). (It's not all that
    unreasonble to have the business logic run in a separate
    process, even if it is on the same machine.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jun 30, 2008
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. 2BaCook
    Replies:
    3
    Views:
    450
    Reinhold Erler
    Nov 11, 2003
  2. kelvSYC
    Replies:
    2
    Views:
    594
    Chris Smith
    Aug 18, 2004
  3. Maciej Pilichowski
    Replies:
    3
    Views:
    3,569
    Duane Hebert
    Jan 9, 2005
  4. pabbu
    Replies:
    8
    Views:
    732
    Marc Boyer
    Nov 7, 2005
  5. Noah Roberts
    Replies:
    238
    Views:
    3,975
    Ian Collins
    Aug 22, 2009
Loading...

Share This Page