473,396 Members | 1,918 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Designing lower level classes.

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.
Jun 29 '08 #1
11 1431
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
Jun 29 '08 #2
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.
Jun 29 '08 #3
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.
Jun 29 '08 #4
On 2008-06-29 16:43, Stefan Ram wrote:
Juha Nieminen <no****@thanks.invalidwrites:
>>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
Jun 29 '08 #5
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?
Jun 29 '08 #6
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.
Jun 29 '08 #7
Stefan Ram wrote:
Gunter Schelfhout <no*****@please.com.invalidwrites:
>>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. ;-)
Jun 29 '08 #8
On 2008-06-29 17:45, Stefan Ram wrote:
Gunter Schelfhout <no*****@please.com.invalidwrites:
>>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
Jun 29 '08 #9
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
Jun 29 '08 #10
Juha Nieminen <no****@thanks.invalidkirjutas:
>
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.
FYI: in our company, we are currently kind of experimenting with a
decoupled GUI-intensive design. The GUI is done by C# programmers and is
supposed to look very shiny and "professional". However, the C#
programmers don't have any glue (and should not) about *what* to display
on the interface. All display content is provided in an "abstract" XML
format from another (C++) background process (possibly on another
computer). Most user interactions (like dragging a gamma correction
scrollbar button) are sent back to the background process, which
prepares new content and notifies the GUI process about the changes in
the displayed content.

Yes, this is a lot of work, and I'm not so convinced it finally pays
off. The reasons for adopting this scheme were more company-political
than technical. However, having a clean separation layer between the
functionality and user interface seems to be a good thing to have. The
project is in the middle so I cannot say yet how it actually works out.

Paavo

Jun 29 '08 #11
On Jun 29, 6:04 pm, r...@zedat.fu-berlin.de (Stefan Ram) wrote:
Juha Nieminen <nos...@thanks.invalidwrites:
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:ja*********@gmail.com
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
Jun 30 '08 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: SuryaPrakash Patel via SQLMonster.com | last post by:
Dear All, How to reach to the highest level of normalization for database designing? Guide Lines Needed. What will be the characteristics of a database of a completely normalized databae? ...
6
by: E G | last post by:
Hi! I am having problems in designing a class. First, I have a base class that allocates a 3D data set and allows some other mathematical operations with it, something like this: template...
3
by: alexhong2001 | last post by:
When design a class, should always make it "derivable" as a base class? Is there really a situation that the designed class not "derivable"? When should make a member "protected"? Only when...
1
by: slonocode | last post by:
I'm wondering if there are certain processes that I could follow to learn to design better classes? Where could I find these processes? Is designing classes more of an art that comes from...
0
by: Julia Beresford | last post by:
Hi I have a VB .NET class library with classes and collection classes (classes that implement ICollection) that allow a client to read and write data to and from an SQL database. For example if...
2
by: Lorenzo Castelli | last post by:
This is an old problem of mine. Basically I have an abstract base class which represents a generic iterator over a collection of elements, and various derived classes that implement the...
5
by: The Cool Giraffe | last post by:
I'm designing an ABC and in connection to that i have run into some "huh!" and "oh...". Let me put it as a list. 1. Since the class will only contain bodies of the methods, only the header file...
1
weaknessforcats
by: weaknessforcats | last post by:
Introduction Polymorphism is the official term for Object-Oriented Programming (OOP). Polymorphism is implemented in C++ by virtual functions. This article uses a simple example hierarchy which...
4
by: Alexey Moskvin | last post by:
Hi! I have a set of strings (all letters are capitalized) at utf-8, russian language. I need to lower it, but my_string.lower(). Doesn't work. See sample script: # -*- coding: utf-8 -*- s1 =...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.