Qt - proper design of application code - c++

It was hard for me to search for related topic, so here is my question. I started using Qt like two days ago, and therefore I don't have any clue how to make it working (on the code-side).
[offtopic]
Here's some history: at first I thought about separating my application's logic from its appearance. I had some core classes, another ones for GUI (displaying and controlling), and some kind of "bridges" between to, for example, move data from class A which had std::list members to class B : public QAbstractListView, which had QStringList. But I gave up, when I had to use more and more Qt code (HTTP requests, disk I/O, regex). My code started looking like a mess, co I thought about refactoring my code.
(Anyways, is it a good idea to merge these two things - application logic into Qt (sub)classes?)
[/offtopic]
And I came to another problem and it's finally related to question in topic: is it better (say, Qt-way), for example, to have a class with private member QWebPage and some public methods, slots and signals to operate on it or simply to add my functionality in subclass of QWebPage?

Inheritance is one of the greatest things of OOP, if used correctly.
A "subclass", in all good OO designs, has to obey a simple rule: IS the child a KIND OF parent? That is usually called, in OOP literature, a "is a" relationship.
And more important: the child has always to do two things: specialize a generic behavior, or extend the functionality of the father. I consider it a code smell when a subclass does neither.
That said, your decision has nothing to do with Qt, or with what's programatically better or worse. It should make sense.
An example: If you had a QLabel that had to show the score of a game, and only that, it could be a good idea to do something like
class MyScoreBoard : public QLabel
{
private:
int scoreP1;
int scoreP2;
Game *_g;
public:
MyScoreBoard(QWidget *parent = 0) :
QLabel(parent)
{
scoreP1 = 0;
scoreP2 = 0;
connect(_g, SIGNAL(scoreChanged(int,int)), this, SLOT(updateScore(int,int)));
}
public slot:
updateScore(int a, int b) {
scoreP1 = a;
scoreP2 = b;
this->setText(QString::number(scoreP1) + "x" + QString::number(scoreP2));
};
};
On the other hand, if your scoreboard had some lights on top of it, that should blink whenever the score had changed, if it had one label for each player, that had to change its color depending on the score, then it would be better to create a ScoreBoard class that HAD two labels, HAD two lights, and then implement the intended behavior.
Bottom line is: inherit if it makes sense on your design
Wikipedia has a good small article about an anti-pattern that appears when inheritance is used without care.

Related

Is forwarding function calls to a member bad practice?

In code I have been writing recently I have been forced to directly access a member of an object to call its functions, however, it feels wrong to do this because it would seem to violate encapsulation and the Law of Demeter. Yet the only good alternative I can come up with is to write my own function in the class for every single function of that member I may want to call, which would be very tedious and redundant. Example:
class Object
{
public:
void setNum(int x)
{
num = x;
}
private:
int num;
};
class Object2
{
public:
Object obj;
};
int main()
{
Object2 obj2;
obj2.obj.setNum(5);
}
vs
class Object
{
public:
void setNum(int x)
{
num = x;
}
private:
int num;
};
class Object2
{
public:
void setNum(int x)
{
obj.setNum(x);
}
private:
Object obj;
};
int main()
{
Object2 obj2;
obj2.setNum(5);
}
The call to setNum in Object2 is forwarded to the same function in Object. Is such a design considered bad practice? Is accessing obj directly be any better?
I could also have Object2 inherit from Object, but in this case the class I would be inheriting from is not designed to be a base class, would expose protected members to Object2, and seems unfitting to begin with because it is not an is-a relationship and composition would be preferred.
My specific situation: I am making a game using SFML, there is a class Ship that of course needs a sprite to represent it in the world. Anytime I want to set or get the ship's position, rotation, etc. I have to either directly access its sprite or write a redundant forwarding function in Ship. The issue is that doing either one of those things seems like a code smell: either violate encapsulation and the Law of Demeter, or write redundant code.
What would be considered best practice here? Am I being overly picky about writing simple forwarding functions? Or is there really nothing wrong with directly accessing the sprite of Ship in this case?
This question: C++ Forward method calls to embed object without inheritance in fact is exactly what I'm asking, however, neither answer gives a good solution. One not being condoned and apparently having very poor encapsulation, the other simply using a getter which seems to be a placebo if anything, and no one addresses the main question I have, which is what is the most elegant and acceptable solution?
What solution is the best highly depends on underlying semantics of encapsulation. You need to decouple your code as much as possible. I'll describe that on examples:
You have a Ship class and it has a Sprite. You may want to separate game logic and rendering. So all that Ships knows about the rendering is that it has a Sprite object which handles it. So in this case you are separating responsibilities and that's good. So simple getter is a good solution.
But if absolute coordinates and rotation must be stored in a sprite, then things change: game logic usually needs them two, so they must be set consistently both inside a Ship and a Sprite. The best way to achieve that is to make Ship's setPosition and setRotation methods to set Sprites position and rotation too. That way you simplify the code which works with the Ship at expense of Ship complexity. Given that Ship is manipulated from several places, that's worth it. NOTE: You still may want to expose Sprite through a getter for rendering purposes. And you may want to prevent anybody except a Ship to set Sprite position and rotation, if that does not bloat your code too much.
Let's imagine that Ship class is mostly devoted to rendering. In such situation you may want to hide from outer classes that you use sprites for graphics (because if you change rendering engine it will be good if you won't need to rewrite anything except rendering code). And in such situation you will want to proxy all setPosition and setRotation calls to a Sprite through Ship just to hide existence of the Sprite.
In none of this cases inheritance is used because inheritance means that child is a variation of it's ancestor. You can say that BattleShip is a variant of a Ship. But Ship is not a variant of a Sprite, they are too different and mean different things.
So: if encapsulated class is too specific and should not be visible outside or if it must be operated consistently with a master object, then writing a bunch of proxy methods is a good solution. Otherwise these methods will just bloat your code and it's better to provide a way to get nested object. But in that case I vote for a getter method instead of a public property.
Despite of how the classic javanese oop school can think, never forgot that also DRY (Don't Repeat Yourself) is ALSO considered a good practice.
And while OOP is just one of many programming paradigm C++ can support, DRY is the very essence of all programming since the first very assembler got macros, and this is true long before oop inventors was even far away from their own parent's thoughts and wishes.
For all what my unfair experience is... if respecting a good oop practice force you in writing useless boilerplates of repeating code it means either
The language you are using is fundamentally broken for the purpose you want to achieve, not supporting the paradigm correctly or...
OOP is broken for the purpose you are try to reach. And in C++ chances are that OOP is really the broken paradigm.
To come to your specific problem, delegation (that's how that pattern is commonly named) makes sense if:
the way it is delegating can be changed or
the delegation is to hide part of the member interface.
In you case, you have a function that calls a fixed method reachable from fixed member.
Is that only specific to this particular sample or in your implementation will be always that way by design?
If so, delegation adds no semantic value, if not just reducing a.b.m() to a.m(). If you are writing more than ... let's say three "do nothing just forward" functions you are wasting your time.
If b has 50 methods and you are making it private to delegate only 5 of them, than it makes perfectly sense.

Qt5 and Pattern for similar dialogs implementation

What is in your opinion the best way to implement similar dialogs in Qt5 without duplicating the code?
This is the problem: having two "slightly different" data structures, with many common parts, implement two "slightly different" QDialog to handle the user interaction.
We have two structures:
class DataA {
public:
int one, two, three;
bool x,y;
SubdataA subA;
}
class DataB {
public:
int one, two, three;
bool x,y;
SubdataB subB;
}
SubdataX is some other structured data we need to handle in the GUI. The two QDialog should handle the common fields the same way, while SubdataX must be handled by specific parts. The code should also make some operation on the data structures, and provide output files. This part is quite easy.
My question is, what are the best strategies to implement this? The objective is to have elegant code that should be quite easy to maintain and as most readable as possible. The framework is Qt, so the solution should be tailored to Qt with qdialog layout in UI files, since the gui layout is too complex to design it by code.
Thank you.
I'm not sure what you mean by "difficult to manage the ancestor class". I think I understand you want a polymorphic input to determine the layout of a dialog box. Is this assumption correct?
For example, given the following classes, you're able to use a dynamic cast to influence the behaviour of a dialog box.
class IData {
public;
int one, two, three;
bool x, y;
};
class DataA : public IData {
public:
// more data in here
};
class DataB : public IData {
public:
// more unique data in here
}
Now, assume you have written a dialog box with a function signature
void configureDialog(IData *data) {
DataA *dataA = dynamic_cast<DataA*>(data);
if (dataA) {
// configure what parts of the QDialog to see here
}
DataB *dataB = dynamic_cast<DataB*>(data);
if (dataB) {
// configure other parts of the QDialog you want to see
}
}
Which would allow for polymorphic configuration of a single QDialog box.
As Tyler Jandreau stated, a possible solution is to use polymorphism.
But this requires a careful planning of architecture and class inheritance, because to avoid using downcasting and a huge and unmaintenable number of switch() cases, you need also to use polymorphism on the GUI classes.
As View/Model architecture requires, the data classes will be mimicked by the control/Gui classes.
Data classes will be implemented using an ancestor, abstract class CommonData that includes the common "fields", and two (or more) concrete data classes derived from CommonData through inheritance. My first idea was to use composition instead, but this would pose other issues when implementing the gui.
So DataA and DataB are derived from CommonData.
On the Gui side, the structure is similar, but due to lack of inheritance support of the UI form classes generated by Qt's uic, we cannot use inheritance. My first guess was to use Template Metaprogramming, and implement the ancestor class as a Template class, but though it worked on the C++ side, moc refuses to parse that class and generate the moc_X file when the Q_OBJECT tagged class is a template.
So we are going to use a mix of inheritance and composition.
This is the architecture: a "container" GUI class (ContainerDialog) implements the GUI for the CommonData class; a PluggableInterface abstract class will define a set of operation (we'll see which below); a set of concrete classes derived from the latter will implement the GUI logic for the remaining classes.
So the ContainerDialog loads a ContainerDialog.ui form as a "standard" QDialog, and manages all the interface with CommonData. His constructor , or a setter will receive a CommonData pointer, remember that CommonData is abstract and cannot be instantiated.
The specific fields are managed thorugh specific graphic components that are "plugged" in the ContainerDialog gui. For example, a method defined in PluggableInterface will insert the QWidget derived component in the ContainerDialog gui. The classes involved are, for example, ComponentA1, ComponentA2, ComponentB, etc...
The use of the abstract interface PluggableInterface and the UI components will prevent the ContainerDialog to know what kind of concrete class are in use, and all the necessary code to instantiate the specific classes can be implemented using some creational pattern (Abstract Factory, Prototypes, etc...)

Accessing subclass functions of member of collection of parent class objects

(Refer Update #1 for a concise version of the question.)
We have an (abstract) class named Games that has subclasses, say BasketBall and Hockey (and probably many more to come later).
Another class GameSchedule, must contain a collection GamesCollection of various Games objects. The issue is that we would, at times, like to iterate only through the BasketBall objects of GamesCollection and call functions that are specific to it (and not mentioned in the Games class).
That is, GameSchedule deals with a number of objects that broadly belong to Games class, in the sense that they do have common functions that are being accessed; at the same time, there is more granularity at which they are to be handled.
We would like to come up with a design that avoids unsafe downcasting, and is extensible in the sense that creating many subclasses under Games or any of its existing subclasses must not necessitate the addition of too much code to handle this requirement.
Examples:
A clumsy solution that I came up with, that doesn't do any downcasting at all, is to have dummy functions in the Game class for every subclass specific function that has to be called from GameSchedule. These dummy functions will have an overriding implementation in the appropriate subclasses which actually require its implementation.
We could explicitly maintain different containers for various subclasses of Games instead of a single container. But this would require a lot of extra code in GameSchedule, when the number of subclasses grow. Especially if we need to iterate through all the Games objects.
Is there a neat way of doing this?
Note: the code is written in C++
Update# 1: I realized that the question can be put in a much simpler way. Is it possible to have a container class for any object belonging to a hierarchy of classes? Moreover, this container class must have the ability to pick elements belonging to (or derive from) a particular class from the hierarchy and return an appropriate list.
In the context of the above problem, the container class must have functions like GetCricketGames, GetTestCricketGames, GetBaseballGame etc.,
This is exactly one of the problems that The "Tell, Don't Ask" principle was created for.
You're describing an object that holds onto references to other objects, and wants to ask them what type of object they are before telling them what they need to do. From the article linked above:
The problem is that, as the caller, you should not be making decisions based on the state of the called object that result in you then changing the state of the object. The logic you are implementing is probably the called object’s responsibility, not yours. For you to make decisions outside the object violates its encapsulation.
If you break the rules of encapsulation, you not only introduce the runtime risks incurred by rampant downcasts, but also make your system significantly less maintainable by making it easier for components to become tightly coupled.
Now that that's out there, let's look at how the "Tell, Don't Ask" could be applied to your design problem.
Let's go through your stated constraints (in no particular order):
GameSchedule needs to iterate over all games, performing general operations
GameSchedule needs to iterate over a subset of all games (e.g., Basketball), to perform type-specific operations
No downcasts
Must easily accommodate new Game subclasses
The first step to following the "Tell, Don't Ask" principle is identifying the actions that will take place in the system. This lets us take a step back and evaluate what the system should be doing, without getting bogged down into the details of how it should be doing it.
You made the following comment in #MarkB's answer:
If there's a TestCricket class inheriting from Cricket, and it has many specific attributes concerning the timings of the various innings of the match, and we would like to initialize the values of all TestCricket objects' timing attributes to some preset value, I need a loop that picks all TestCricket objects and calls some function like setInningTimings(int inning_index, Time_Object t)
In this case, the action is: "Initialize the inning timings of all TestCricket games to a preset value."
This is problematic, because the code that wants to perform this initialization is unable to differentiate between TestCricket games, and other games (e.g., Basketball). But maybe it doesn't need to...
Most games have some element of time: Basketball games have time-limited periods, while Baseball games have (basically) innings with basically unlimited time. Each type of game could have its own completely unique configuration. This is not something we want to offload onto a single class.
Instead of asking each game what type of Game it is, and then telling it how to initialize, consider how things would work if the GameSchedule simply told each Game object to initialize. This delegates the responsibility of the initialization to the subclass of Game - the class with literally the most knowledge of what type of game it is.
This can feel really weird at first, because the GameSchedule object is relinquishing control to another object. This is an example of the Hollywood Principle. It's a completely different way of solving problems than the approach most developers initially learn.
This approach deals with the constraints in the following ways:
GameSchedule can iterate over a list of Games without any problem
GameSchedule no longer needs to know the subtypes of its Games
No downcasting is necessary, because the subclasses themselves are handling the subclass-specific logic
When a new subclass is added, no logic needs to be changed anywhere - the subclass itself implements the necessary details (e.g., an InitializeTiming() method).
Edit: Here's an example, as a proof-of-concept.
struct Game
{
std::string m_name;
Game(std::string name)
: m_name(name)
{
}
virtual void Start() = 0;
virtual void InitializeTiming() = 0;
};
// A class to demonstrate a collaborating object
struct PeriodLengthProvider
{
int GetPeriodLength();
}
struct Basketball : Game
{
int m_period_length;
PeriodLengthProvider* m_period_length_provider;
Basketball(PeriodLengthProvider* period_length_provider)
: Game("Basketball")
, m_period_length_provider(period_length_provider)
{
}
void Start() override;
void InitializeTiming() override
{
m_period_length = m_time_provider->GetPeriodLength();
}
};
struct Baseball : Game
{
int m_number_of_innings;
Baseball() : Game("Baseball") { }
void Start() override;
void InitializeTiming() override
{
m_number_of_innings = 9;
}
}
struct GameSchedule
{
std::vector<Game*> m_games;
GameSchedule(std::vector<Game*> games)
: m_games(games)
{
}
void StartGames()
{
for(auto& game : m_games)
{
game->InitializeTiming();
game->Start();
}
}
};
You've already identified the first two options that came to my mind: Make the base class have the methods in question, or maintain separate containers for each game type.
The fact that you don't feel these are appropriate leads me to believe that the "abstract" interface you provide in the Game base class may be far too concrete. I suspect that what you need to do is step back and look at the base interface.
You haven't given any concrete example to help, so I'm going to make one up. Let's say your basketball class has a NextQuarter method and hockey has NextPeriod. Instead, add to the base class a NextGameSegment method, or something that abstracts away the game-specific details. All the game-specific implementation details should be hidden in the child class with only a game-general interface needed by the schedule class.
C# supports reflections and by using the "is" keyword or GetType() member function you could do these easily. If you are writing your code in unmanaged C++, I think the best way to do this is add a GetType() method in your base class (Games?). Which in its turn would return an enum, containing all the classes that derive from it (so you would have to create an enum too) for that. That way you can safely determine the type you are dealing with only through the base type. Below is an example:
enum class GameTypes { Game, Basketball, Football, Hockey };
class Game
{
public:
virtual GameTypes GetType() { return GameTypes::Game; }
}
class BasketBall : public Game
{
public:
GameTypes GetType() { return GameTypes::Basketball; }
}
and you do this for the remaining games (e.g. Football, Hockey). Then you keep a container of Game objects only. As you get the Game object, you call its GetType() method and effectively determine its type.
You're trying to have it all, and you can't do that. :) Either you need to do a downcast, or you'll need to utilize something like the visitor pattern that would then require you to do work every time you create a new implementation of Game. Or you can fundamentally redesign things to eliminate the need to pick the individual Basketballs out of a collection of Games.
And FWIW: downcasting may be ugly, but it's not unsafe as long as you use pointers and check for null:
for(Game* game : allGames)
{
Basketball* bball = dynamic_cast<Basketball*>(game);
if(bball != nullptr)
bball->SetupCourt();
}
I'd use the strategy pattern here.
Each game type has its own scheduling strategy which derives from the common strategy used by your game schedule class and decouples the dependency between the specific game and game schedule.

How should a basic class hierarchy be constructed? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I know how to code and use simple classes, and I even know how inheritance works and how to use it. However, there's a very limited amount of guides on how to actually design the structure of your class hierarchy, or even how to design a simple class? Also, when and why should I inherit (or use) a class?
So I'm not really asking about how, I'm asking when and why. Example codes are always a good way to learn, so I would appreciate them. Also, emphasize the progress of designing rather than simply giving one sentence on when and why.
I program mainly in C++, C# and Python, but I'll probably understand the simple examples in most languages.
If any of the terms seem mixed up or so, feel free to edit my question. I'm not a native and I'm not sure of all the words.
I'll use C++ as an example language, since it relies so much on inheritance and classes.
Here's a simple guide on how to build controls for a simple OS, such as windows.
Controls include simple objects on your windows, such as buttons, sliders, textboxes, etc.
Building a basic class.
This part of the guide applies for (almost) any class.
Remember, well planned is half done.
What kind of class are we working on?
Which are it's attributes and what methods does it need?
These are the main questions we need to think of.
We're working on OS controls here, so let's begin with a simple class, shall it be Button. Now, what are the attributes on our button? Obviously it needs a position on the window. Also, we don't want every button to be exact same size, so size is an other attribute. Button also "needs" a label (the text drawn on the button). This is what you do with each class, you design it and then code it. Now I know which attributes I need, so lets build the class.
class Button
{
private:
Point m_position;
Size m_size;
std::string m_label;
}
Notice how I've left out all the getters and setter and other methods for the sake of shorter code, but you'd have to include those too. I'm also expecting us to have Point and Size classes, normally we'd have to struct them ourselves.
Moving onto the next class.
Now that we got one class (Button) finished, we can move to the next class.
Let's go with Slider, the bar which e.g. helps you scroll web pages up and down.
Let's begin like we did on button, what does our slider class need?
It's got location (position) on the window and size of the slider. Also, it's got minimum and maximum values (minimum means that the scroller is set to the top of the slider, and maximum means it's on the bottom). We also need the current value, i.e. where the scroller is at the moment. This is enough for now, we can build our class:
class Slider
{
private:
Point m_position;
Size m_size;
int m_minValue;
int m_maxValue;
int m_currentValue;
}
Creating a base class.
Now that we got two classes, the first thing we notice is we just defined Point m_position; and Size m_size; attributes on both classes. This means we have two classes with common elements and we just wrote the same code twice, wouldn't it be awesome if we could write the code only once and tell both of our classes to use that code instead of rewriting? Well, we can.
Creating a base class is "always" (there are exceptions, but beginners shouldn't worry about them) recommended if we have two similar classes with common attributes, in this case Button and Slider. They are both controls on our OS with size and position. From this we get a new class, called Control:
class Control
{
private:
Point m_position;
Size m_size;
}
Inheriting similar classes from common base class.
Now that we got our Control class, which includes the common items for every control, we can tell our Button and Slider to inherit from it. This will save us time, computer's memory and eventually time. Here's our new classes:
class Control
{
private:
Point m_position;
Size m_size;
}
class Button : public Control
{
private:
std::string m_label
}
class Slider : public Control
{
private:
int m_minValue;
int m_maxValue;
int m_currentValue;
}
Now some people might say that writing Point m_position; Size m_size; twice is much easier than writing twice : public Control and creating the Control class.
This might be true in some cases, but it's still recommended not to write the same code twice, especially not when creating classes.
Besides, who knows how many common attributes we'll eventually find. Later on we might realize we need Control* m_parent member to the Control class, which points to the window (or panel or such) in which our control is held in.
An other thing is, if we later on realize that on top of Slider and Button we also need TextBox, we can just create a textbox control by saying class TextBox : public Control { ... } and only write the textbox specific member variables, instead of size, position and parent again and again on every class.
Final thoughts.
Basically always when you have two classes with common attributes or methods, you should create a base class.
This is the basic rule, but you are allowed to use your own brain since there might be some exceptions.
I am not a professional coder myself either, but I'm learning and I've taught you everything as my educators have taught it to me. I hope you (or atleast someone) will find this answer useful.
And even though some people say that python and other duck typing languages don't even need to use inheritance, they're wrong.
Using inheritance will save you so much time and money on larger projects, and eventually you'll thank yourself for creating the base classes.
The reusability and management of your project will become billion times easier.
You need to use inheritance, when you have a situation where there are two classes, that contains the attributes of a single class, or when there are two classes, in which one is dependant on the other. Eg)
class animal:
#something
class dog(animal):
#something
class cat(animal):
#something
Here, there are two classes , dog and cat, that have the attributes of the class animal. Here , inheritance plays its role.
class parent:
#something
class child(parent):
#something
Here, parent and child are two classes, where the child is dependant of the parent, where the child has the attributes of the parent and its own unique ones. So, inheritance is used here.
It depends on the language.
In Python for example you normally don't need a lot of inheritance because you can pass any object to any function and if the objects implements the proper methods everything will be fine.
class Dog:
def __init__(self, name):
self.name = name
def sing(self):
return self.name + " barks"
class Cat:
def __init__(self, name):
self.name = name
def sing(self):
return self.name + " meows"
In the above code Dog and Cat are unrelated classes, but you can pass an instance of either to a function that uses name and calls method sing.
In C++ instead you would be forced to add a base class (e.g. Animal) and to declare those two classes as derived.
Of course inheritance is implemented and useful in Python too, but in many cases in which it's necessary in say C++ or Java you can just avoid it thanks to "duck typing".
However if you want for example to inherit implementation of some methods (in this case the constructor) then inheritance could be use with Python too with
class Animal:
def __init__(self, name):
self.name = name
class Dog(Animal):
def sing(self):
return self.name + " barks"
class Cat(Animal):
def sing(self):
return self.name + " meows"
The dark side of inheritance is that your classes will be more coupled and more difficult to reuse in other contexts you cannot foresee now.
Someone said that with object oriented programming (actually class oriented programming) sometimes you just need a banana and instead you get a gorilla holding a banana and a whole jungle with it.
I'd start with definition of class from wikipedia:
In object-oriented programming, a class is a construct that is used to
create instances of itself – referred to as class instances, class
objects, instance objects or simply objects. A class defines
constituent members which enable its instances to have state and
behavior. Data field members (member variables or instance variables)
enable a class instance to maintain state. Other kinds of members,
especially methods, enable the behavior of class instances. Classes
define the type of their instances
Often you see examples that uses dogs, animals, cats and so on. But let's get to something practical.
First and most straight forward case when you need a class is when you need (or rather you should) to encapsulate certain functions and methods together, because they simply make sense together. Let's imagine something simple: HTTP request.
What do you need when creating HTTP request? Server, port, protocol, headers, URI... You could put all that into dict like {'server': 'google.com'} but when you use class for this, you'll just make it explicit that you need these attributes together and you'll be using them to do this one particular task.
For the methods. You could again create method fetch(dict_of_settings), but whole functionality is bound to attributes of HTTP class and just doesn't make sense without them.
class HTTP:
def __init__(self):
self.server = ...
self.port = ...
...
def fetch(self):
connect to self.server on port self.port
...
r1 = HTTP(...)
r2 = HTTP(...)
r1.port = ...
data = r1.fetch()
Isn't it nice and readable?
Abstract classes/Interfaces
This point, just quick... Assume you want to implement dependency injection in your project for this particular case: you want your application to be independent on database engine.
So you propose interface (represented by abstract class) which should each database connector implement and then rely on generic methods in your application. Lets say that you define DatabaseConnectorAbstract (you don't have to actually define in python, but you do in C++/C# when proposing interface) with methods:
class DatabaseConnectorAbstract:
def connect(): raise NotImplementedError( )
def fetch_articles_list(): raise NotImplementedError( )
...
# And build mysql implementation
class DatabaseConnectorMysql(DatabaseConnectorAbstract):
...
# And finally use it in your application
class Application:
def __init__(self,database_connector):
if not isinstanceof(database_connector, DatabaseConnectorAbstract):
raise TypeError()
# And now you can rely that database_connector either implements all
# required methods or raises not implemented exception
Class hierarchy
Python exceptions. Just take a look for a second on the hierarchy there.
ArithmeticError is generic Exception and in some cases it can get as particular as saying FloatingPointError. This is extremely useful when handling exceptions.
You can realize this better on .NET forms when object has to be instance of Control when adding to form, but can be practically anything else. The whole point is that object is DataGridView while still being Control (and implementing all methods and properties). This is closely connected with abstract classes and interfaces and one of many real-life examples could be HTML elements:
class HtmlElement: pass # Provides basic escaping
class HtmlInput(HtmlElement): pass # Adds handling for values and types
class HtmlSelect(HtmlInput): pass # Select is input with multiple options
class HtmlContainer(HtmlElement): pass # div,p... can contain unlimited number of HtmlElements
class HtmlForm(HtmlContainer): pass # Handles action, method, onsubmit
I've tried to make it as brief as possible, so feel free to ask in comment.
Since you are primarily interested in the big picture, and not the mechanics of class design, you might want to familiarize yourself with the S.O.L.I.D. principles of object-oriented design. It's not a strict procedure, but a set or rules to support your own judgement and taste.
The essence is that a class represents a single responsiblity (the S). It does one thing and does it well. It should represent an abstraction, preferably one representing a piece of your application's logic (encapsulating both behavior and data to support that behavior). It could also be an aggregation abstraction of multiple related data field. The class is the unit of such encapsulation and is responsible for maintaining the invariants of your abstractions.
The way to build classes is to be both open to extensions and closed to modifications (the O). Identify likely changes in your class's dependencies (either types or constants that you used in its interface and implementation). You want the interface to be complete enough so that it can extended, yet you want its implementation to be robust enough so that it won't have to be changed for that.
That's two principles about the class as the basic building block. Now on to building hierarchies, which represents class relationships.
Hierarchies are built through inheritance or composition. The key principle here is that you only use inheritance to model strict Liskov-substitutability (the L). This is a fancy way of saying that you only use inheritance for is-a relationships. For anything else (barring some technical exceptions to get some minor implementation advantages) you use composition. This will keep your system as loosely coupled as possible.
At some point many different clients might depend on your classes for different reasons. This will grow your class hierarchy and some of the classes lower in the hierarchy can get overly large ("fat") interfaces. When that happens (and in practice it's a matter of taste and judgement) you seggregate your general-purpose class interface into many client-specific interfaces (the I).
As your hierarchy grows even further, it might appear to form a pyramid when you draw it with the basic classes on top and their subclasses or composities below it. This will mean that your higher-level application layers will depend on lower-level details. You can avoid such brittleness (which for example manifests itself through large compile times or very big cascades of changes following minor refactorings) by letting both the higher-level layer and the lower-level layer depend on abstractions (i.e. interfaces, which in C++ e.g. can be implemented as abstract classes or template parameters). Such dependency inversion (the D) once again helps to loosen couplings between the various parts of your application.
That's it: five solid pieces of advice that are more or less language independent and have stood the test of time. Software design is hard, these rules are to keep you out of the most frequently occuring types of trouble, everything else comes through practice.

Organization of the QT Code

I am writing an application of middle size. I will have many gui components and many classes. However, it is difficult for me to organize the code, to separate the logic, ... For example, let say that I press one button that creates an object of a class and perform a computation on that object. After exiting the slot function of the button, this local object is destroyed. What if I need it in another function later? Defining everything as a global variable in the header file is not a good thing for me. So I was thinking of a static class that contains somehow pointers to all the objects I will need later. Does anybody has a better idea?
How to manage objects inside an application is always a tricky
question. Qt goes down a very object-oriented route and uses reference
semantics implemented through pointer for nearly everything. To
prevent tedious manual memory management Qt organizes everything into
Object Trees. This
is augmented by Qt own
object model that adds
some dynamic capabilities.
If you want to go down that route, stick to everything Qt provides. It
is much more similar to Java than the usual C++ approach and might be
more comforting for beginners and maybe suits your application
domain. It tightly ties your code to Qt and will make it hard to
separate from it.
One other approach means to simply forgo all Qt stuff and work out the
core logic of your application. Develop it in pure C++ and than have a
thin layer that ties this logic into your Qt application through
signals and slots. In such an approach you would opt to use more
value-semantics.
For your concrete example of creating an algorithm and keeping it
around. The Qt approach:
class MyAlgo : public QObject {
Q_OBJECT
public:
MyAlgo(QObject* o) : QObject(o) { }
virtual compute();
};
// use it in a mainwindow slot
void MainWindow::executeAlgorithm(const QString& name) {
MyAlgo* algo = this->findChild<MyAlgo*>(name);
if(!algo) {
// not found, create
algo = new MyAlgo(this); // make mainwindow the parent of this algo
algo->setName(name); // QObject name property
}
algo->compute();
}