Results 1 to 20 of 20

Thread: Application architecture

  1. #1
    Join Date
    Jan 2010
    Location
    Poland Warsaw
    Posts
    25
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Application architecture

    Hello!

    I have question about architectures of applications you write.

    When I create new Qt application using QtCreator it creates main.cpp, mainwindow.h/cpp and other files. MainWindow object is created in main.cpp. When I write another classes (eg. for db or hardware access) I would like to separate them from MainWindow class (objects of "other" classes are not created in MainWindow). So their instances (I think) should be outside of MainWindow class but I'm not sure main.cpp is good place for this. Simultaneously I would like to send signals between GUI and other objects.

    I am curious how you organize your applications. I realize that it depends on purpose of application and its complexity but some diagrams would be very useful.

    Thanks.

  2. #2
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Application architecture

    When I write another classes (eg. for db or hardware access) I would like to separate them from MainWindow class (objects of "other" classes are not created in MainWindow). So their instances (I think) should be outside of MainWindow class but I'm not sure main.cpp is good place for this.
    If I understand you correctly, then it seems you are confusing things.
    Its true that FUNCTIONALITY should be encapsulated (be it classes, methods or other scopes).
    Then you talk about separation.
    But if you need to access what ever functionality, then you should and must have access to the object that encapsulates that functionality.
    So you very well might need objects that encapsulate hardware access (for example) in your GUI.

    Is this your first project in C++?
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  3. #3
    Join Date
    Jan 2010
    Location
    Poland Warsaw
    Posts
    25
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Application architecture

    Thanks for your reply.

    No. It is not my first project. But I have problem with writing applications which can be easily modified.
    Is it normal that objects responsible for some functionalities are created in GUI objects?

  4. #4
    Join Date
    Sep 2010
    Location
    Poland
    Posts
    112
    Thanks
    8
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Maemo/MeeGo

    Default Re: Application architecture

    what you're asking about can be found here
    http://doc.qt.nokia.com/4.7-snapshot...ogramming.html

    one basic rule is to extract all code interacting with data from the qui code
    and yes, you need to create an object which can be describe as a bridge between gui and data itself
    My schedule makes my cry
    My works makes my laugh
    My life makes... oh...no....

  5. #5
    Join Date
    Jan 2010
    Location
    Poland Warsaw
    Posts
    25
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Application architecture

    Could you give some simple example?

  6. #6
    Join Date
    Sep 2009
    Location
    Wroclaw, Poland
    Posts
    1,394
    Thanked 342 Times in 324 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Application architecture

    Could you give some simple example?
    Lets say you have some entities stored in xml file. To read and modify those files you can create a class (pseudocode):
    Qt Code:
    1. class FileParser{
    2. public:
    3. List<Data> readData( string file );
    4. void saveData( List<Data>, string out_file );
    5. };
    To copy to clipboard, switch view to plain text mode 

    The only responsibility of this class is to hide all the details associated with Data storage in your files and provide an interface to access them.
    Now, maybe you'll want to display some data in a ListWidget, no problem, you have method to access a list of entities stored in a file ( List<Data> readData(file) ), so you can create a method:
    Qt Code:
    1. void ListWidget::displayData( file ){
    2. FileParser parser;
    3. List<Data> data = parser.readData(file);
    4. foreach( Data d, data ){
    5. this->displayEntity(d);
    6. }
    To copy to clipboard, switch view to plain text mode 
    or you can create a function that prints the data to stdout somehow.

    There could be, for example, a HardwareMonitor that you use to read CPU temperature instead of file parser:
    Qt Code:
    1. class HardMonitor{
    2. public:
    3. int cpuTemperature();
    4. private:
    5. HardwareMonitorImpl _impl; //!< this object can hide the details of implementation for different operating systems
    6. };
    To copy to clipboard, switch view to plain text mode 

    If you want to display CPU temp in your GUI you wont escape creating a HardMonitor object (same for previous example). But the fact that details of accessing underlying data are hidden makes your application more flexible, eg. it wont hurt that much if you want to replace xml storage schema with some other data format, or provide new way to get CPU temperature. Client classes that uses FileParser or HardMonitor wont be affected by this change, as the only thing they see is the interface.

    I hope this will be of any use for you.

  7. #7
    Join Date
    Sep 2010
    Location
    Poland
    Posts
    112
    Thanks
    8
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Maemo/MeeGo

    Default Re: Application architecture

    example could be simple computing or data processing
    for example you click the button by which you request for data from the database and you expect this data to be displayed with some funky graphical stuff
    to do so you a class which will do this job
    so you encapsulate all the functionality you need in the class and what's left is to call suitable method inside the gui which will process/return formatted date

    stampede's example is better, I just do not know how to explain something sometimes
    Last edited by kornicameister; 4th February 2011 at 21:57.
    My schedule makes my cry
    My works makes my laugh
    My life makes... oh...no....

  8. #8
    Join Date
    Jan 2010
    Location
    Poland Warsaw
    Posts
    25
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Application architecture

    Thanks for your replies!

    I understand that there should be separate classes for GUI, for data access and data processing. That's clear for me.

    But as usual I have another question. Because the object responsible for the GUI is created in the "main.cpp" file, should I treat it as a base object, and create objects responsible for data processing in GUI objects (and in objects responsible for data processing create objects of data access layer)? Or maybe objects of different layers (GUI, data processing, data access, ...) should exist side by side?
    Which approach is better?

  9. #9
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Application architecture

    I started off programming in the Microsoft MFC environment, and probably spent close to 15 years doing that before being saved by Qt. However, some things from that experience got stuck because they are reasonably good solutions to architecture problems.

    First, I always derive my own app class from QApplication. This class holds any information which is global to the entire app. For example, most of the applications I write are chemistry-based, so the App class holds the global instance of the Periodic Table that is used in all chemical formula calculations. Many of my apps are licensed, so I have a QLicensedApp class, derived from QApplication, that does all that for me and serves as the base class of the actual App class.

    Second, the App class always creates at least one Document class. This class is also sort of global, since it lives in the App class, but unlike the other information it can be destroyed and replaced when the user chooses "File->New" from the menu. The Document class is usually derived from QObject so it can use signals and slots.

    Third, all information maintained by the Document class is pure C++ (*not* Qt). I use STL containers, boost smart pointers, etc. so that the algorithms and other data used in the document can be moved to any other standard C++ environment, Qt or not. It is because all of the core algorithms and data structures I use are in this standard C++ that I was able to immediately switch from Microsoft MFC to Qt *without* having to change any of it. My coworkers are still using MFC, and we share all the same algorithms and data structures without changes.

    Fourth, the Document communicates with the rest of the application GUI using signals and slots. This makes for a loose coupling between the Document and the GUI. The Document provides slots so the GUI can cause it to do things with the information it is storing. When that information is changed, it emits a signal. Usually a parameter to the signal is a pointer or const reference to the C++ object that was changed, so any slot listening for the signal knows nothing about the document contents.

    Fifth, almost all GUI interaction runs through the MainWindow class. All menus, toolbars, context menus, etc. are based on QAction items created by the MainWindow. In addition, most of the rest of the GUI is constructed by the MainWindow, and signal and slot connections between the Document and the other GUI components are made in the MainWindow. This adds further decoupling. since the MainWindow ends up being the only GUI class that knows about the signals and slots of the Document. The other GUI classes know nothing about the Document, they are just listening on their slots or sending signals when the user does something.

    Sixth, I use Model/View components extensively. For each collection of information stored in the Document, there is usually a Model that serves as the interface between the Document and the table, tree, or other widget that displays it. These Models are owned by the MainWindow. Typically, the Document emits a "collectionChanged( const SomeCollection & )" signal, and the Model listens for it on a matching slot. The Model stores the pointer to the collection that is passed by the Document in its signal, and serves it up via the Model's data() method.

    With this basic architecture of App - Document(s) - MainWindow - Rest of the GUI, I have a very flexible way to build, modify, and extend applications, and to create GUI components that can be reused by other applications. If my customer says, "I'd rather see this information presented as a table instead of a tree", in most cases the only thing I have to change is the part of the GUI that creates a table instead of a tree. Maybe the model needs some fixing, too, but none of the rest of anything needs to be touched.

  10. The following user says thank you to d_stranz for this useful post:

    m15ch4 (6th February 2011)

  11. #10
    Join Date
    Jan 2010
    Location
    Poland Warsaw
    Posts
    25
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Application architecture

    d_stranz:
    If you do signal/slot connections in the MainWindow class then you must include the header files of your QLecenseApp and classes that receive signals in MainWindow.cpp. And vice versa. Am I right?

  12. #11
    Join Date
    Jun 2007
    Location
    India
    Posts
    1,042
    Thanks
    8
    Thanked 133 Times in 128 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Application architecture

    instead of subclassing qapplication, why not have a seperate global class?

  13. #12
    Join Date
    Jan 2010
    Location
    Poland Warsaw
    Posts
    25
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Application architecture

    nish: Maybe because you can have access to QApplication through "qApp".

  14. #13
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Application architecture

    Actually, LicensedApp is only used in main.cpp. The MainWindow class does not know anything about the QApplication class. So, a typical main() would look like this:

    Qt Code:
    1. int main(int argc, char *argv[])
    2. {
    3. MyApp app( argc, argv ); // derived from LicensedApp
    4. if ( app.IsLicensed() )
    5. {
    6. // For a single-document app, MyApp has a MyDoc member variable
    7. MyDoc * pDoc = app.GetDocument();
    8.  
    9. // Configure document with any startup parameters
    10. // ...
    11.  
    12. // MainWindow gets built with the Doc pointer
    13. MyMainWindow mainWindow( pDoc );
    14. mainWindow.show();
    15.  
    16. app.connect( &app, SIGNAL( lastWindowClosed() ), &app, SLOT( quit() ) );
    17.  
    18. // Licensing uses a USB stick, so make sure the stick is always inserted
    19. app.MonitorLicense();
    20. retVal = app.exec();
    21. }
    22. else
    23. QMessageBox::critical( 0, "Application - Fatal Error", "Unregistered or license not valid. Application cannot continue." );
    24. }
    To copy to clipboard, switch view to plain text mode 

    So MainWindow.[h, cpp] does not include MyApp.h anywhere. However, it -does- need MyDoc.h because it needs to connect to MyDoc signals and slots. Since MainWindow is responsible for building the other parts of the GUI, it also needs to include header files for those other widgets, too. But those other widgets do not include MainWindow.h or MyDoc.h, since everything they know comes in from a slot or goes out through a signal. They don't know who is sending the signals to them, or who is receiving theirs.

    So for example, if MyDoc has an array of data and that data gets changed somehow (maybe a menu item opens a file and reads it in, then the MainWindow sticks it into the document through a MainWindow::setData() signal / MyDoc:: onSetData() slot). The document does whatever it needs to do to update its internal state, then emits a MyDoc::dataChanged( const MyDataArray & ) signal.

    And maybe one of the GUI windows has a table that displays that data. It needs a slot to listen for the dataChanged() signal. But it doesn't need to know anything about the document, all it needs to know about is "MyDataArray", so it includes the MyDataArray.h file.

    For an analogy, think about the way spy networks operate. No one knows everything, because that would be a big security risk. So, the spy who is responsible for watching some target only knows he has to watch the target and report what he sees. He doesn't know why he watches the target, he just has his job. Each day, he writes his report and hides it under a rock in the park. Some other spy comes by in the night and removes the report and leaves the instructions for the next day.

    The first spy doesn't know anything except "get instructions from under the rock" and "put reports in their place". The second spy only knows "get reports from under the rock" and "leave instructions in their place". Neither spy knows each other, and all communication is through the rock, so each spy needs to know how the rock works and nothing else.

    The Spy #3 knows a little bit more, because he has set up the connection between Spy #1 and Spy #2 using the rock. So he tells Spy #1, "leave your reports and look for instructions under the rock near the water fountain in the park" and he tells Spy #2 "pick up reports and leave new instructions under the rock...". Spy #3 sends this information to Spy #1 using a different rock and to Spy #2 using a hole in the big tree.

    In the end, each player needs to know only as much about the whole plot as he needs to perform his job. Mr. Big, who is running the network (and keeps all the information he is gathering in his Document), really doesn't know any of the other spies except for the ones he is in immediate contact with. And his communication with them is through signals like "New target needs watching" or slots like "New information received on Target X".

    So in my case, each of the GUI windows I have generally deal with displaying or editing only a single data structure, so they need to include the header file that declares that data structure and its methods. The MainWindow sets up the communication between the Document and the GUI, so the GUI doesn't need to know about the Document or vice-versa. The MainWindow needs to know about both, of course, so it includes the header files for the Document and the GUI window. But if the information in the signals and slots is passed as pointers (*) or references (&), then it -doesn't- need the MyDataArray.h file. It just needs a declaration like "class MyDataArray;" since it isn't going to look at any of the information in the signal or slot, it's just making the connections.

  15. #14
    Join Date
    Jun 2007
    Location
    India
    Posts
    1,042
    Thanks
    8
    Thanked 133 Times in 128 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Application architecture

    nish: Maybe because you can have access to QApplication through "qApp".
    But then qApp needs to be casted to MyApp* everytime they need to use it. And MyApp.h need to included anyway. I dont see any benefit in this.

    Quote Originally Posted by d_stranz View Post
    Actually, LicensedApp is only used in main.cpp. The MainWindow class does not know anything about the QApplication class.
    If it only used in main() they why create an dependency on inheriting QApp? Application security deserves its own separate class, And you can use it in you MFC then.


    So, a typical main() would look like this:

    Qt Code:
    1. int main(int argc, char *argv[])
    2. {
    3. MyApp app( argc, argv ); // derived from LicensedApp
    4. if ( app.IsLicensed() )
    5. {
    6. // Licensing uses a USB stick, so make sure the stick is always inserted
    7. app.MonitorLicense();
    8. retVal = app.exec();
    9. }
    10. else
    11. QMessageBox::critical( 0, "Application - Fatal Error", "Unregistered or license not valid. Application cannot continue." );
    12. }
    To copy to clipboard, switch view to plain text mode 
    I really hope that it is just an example main(). Because it just take a two byte patch to defeat this protection.

  16. #15
    Join Date
    Jan 2010
    Location
    Poland Warsaw
    Posts
    25
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Application architecture

    nish:

    Perhaps you could introduce some example applications organization. It would be very helpful and would look at the problem from another perspective (especially if you include a bit of pseudocode).

    Thanks for all answers.

  17. #16
    Join Date
    Jun 2007
    Location
    India
    Posts
    1,042
    Thanks
    8
    Thanked 133 Times in 128 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Application architecture

    Quote Originally Posted by m15ch4 View Post
    Perhaps you could introduce some example applications organization. It would be very helpful and would look at the problem from another perspective (especially if you include a bit of pseudocode).

    Thanks for all answers.
    The example you provided is very good and most of apps i worked on were using the similar approach.

    Coming to the QApplication issue.
    Inheriting from QApp should be done when you want to extend the original class's functionality. For example QApplication extends QCoreApplication to provide GUI.
    Now lets suppose you app is requried to run in console mode, then you need to use QCoreApplication, which you cant because you are inheriting from QApplication.
    Similarly you cannot use other Classes like QtSignleApplication (inherites from QApplication), because now you have to change your MyApp code to inherit from QtSignleApplication.

    Furthurmore, you are designing you main Security class inherited from QApplication, which makes it Qt depended. All your serial generation/comparision etc should be independent of Qt to use in in any C++ as you mentioned.

    I can explain why your protection in main() is easy to defeat, but i dont think they are implemented as such in your real program.

  18. #17
    Join Date
    Jan 2010
    Location
    Poland Warsaw
    Posts
    25
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Application architecture

    nish:
    instead of subclassing qapplication, why not have a seperate global class?
    Did you mean that instead of creating objects (MainWindow, DataProcess, DataAccess, ...) in the main.cpp file (or QApp class) we should create those objects in separate class (eg. Engine) which will be instantiated in main.cpp?

  19. #18
    Join Date
    Jun 2007
    Location
    India
    Posts
    1,042
    Thanks
    8
    Thanked 133 Times in 128 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Application architecture

    not really. I already agreed that your design is good. Its just the case of Inheriting from QApp that is think should be revisited.

  20. #19
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Application architecture

    Furthurmore, you are designing you main Security class inherited from QApplication, which makes it Qt depended. All your serial generation/comparision etc should be independent of Qt to use in in any C++ as you mentioned.
    I should make clear that all of the security functions -are- implemented independently of my LicensedApp class; this class -is- the Qt wrapper that gives access to the non-Qt security features and exists mainly to supply an event loop. These are in fact shared with non-Qt (e.g. MFC) apps.

  21. #20
    Join Date
    Jan 2010
    Location
    Poland Warsaw
    Posts
    25
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Application architecture

    d_stranz:
    Sixth, I use Model/View components extensively. For each collection of information stored in the Document, there is usually a Model that serves as the interface between the Document and the table, tree, or other widget that displays it. These Models are owned by the MainWindow. Typically, the Document emits a "collectionChanged( const SomeCollection & )" signal, and the Model listens for it on a matching slot. The Model stores the pointer to the collection that is passed by the Document in its signal, and serves it up via the Model's data() method.
    Do you write your own Model classes or you use those from Qt (like QAbstractItemModel)? If your data is stored in custom collection, then you probably have to reimplement at least data() method to fit your data organization (in SomeCollection).

    I would be very thankful if you could explain this.

Similar Threads

  1. Replies: 0
    Last Post: 31st December 2010, 05:46
  2. Three tire architecture for database application ?
    By SudaNix in forum General Programming
    Replies: 1
    Last Post: 19th October 2010, 10:20
  3. Advice needed for QT application architecture
    By hubbobubbo in forum Qt Programming
    Replies: 0
    Last Post: 14th December 2009, 11:30
  4. Replies: 1
    Last Post: 16th September 2008, 17:29
  5. Application plug-in architecture
    By brcain in forum Qt Programming
    Replies: 3
    Last Post: 13th September 2006, 00:39

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.