Storing/uncoupling behaviour - c++

I am making use of the Type Object pattern (as described on gameprogrammingpatterns.com), which was just what I needed to avoid redundancy of data and make it easier to reduce hardcoding. In short I have something like this:
class Action
{
// ...
ActionType& Type;
}
where ActionType is the type object that holds static data for this particular type of Action. There will be several instances of Action, so the memory expenditure is reduced considerably (as compared to storing the type data in each Action instance). It also makes it possible to load action type parameters from a script, but it doesn't work with behavior.
I'm finding it necessary to derive from Action to support different behavior, which kind of defeats the purpose. I could of course use some sort of callable object to parametrize behavior in the ActionType object, but that would still necessitate hardcoding.
How does one go about something like this? Scripting? If that is the way, is it possible to precompile a script for better performance in the release?
Update: To clarify, each Action has an OnUpdate() function that I want to customize for every type of action, without involving inheritance and hardcoding.

Related

Associating types with each other

I have an Action class from which I derive several subtypes. Now, I need to associate some of these subtypes with each other, in a one-to-many relationship. The idea is that some types of Action subtype will make other subtypes available/unavailable (i.e. I also need to create them on the fly). Since in a language like C++ you cannot store type variables the only thing that makes sense is an association of string typenames.
Has anyone met a similar situation? And if so, would you simply use a non-unique associative container like std::multimap and then manually hardcode a huge switch statement for the string-type association?
Example: An action of type Attackwill eventually make Retreat available to its actor, as well as others, like Charge etc. Each action constructor takes at least one Actor reference, but it may also take other, unknown at compile-time, parameters. This last bit makes it very difficult to model this as a decision/action tree... in other words, it seems like I have to build the decision tree during runtime.

C++ pattern for multiple "worker classes" that manipulate a large data class

I have a single very large data class (really a struct, honestly), which needs to be manipulated in enough different ways that I don't just want to implement all of the manipulators as member methods of the data class.
Right now, I have the manipulators set up as singletons, or small instantiated classes held by some manager object, and I pass every manipulator a pointer to the data class during initialization. This works, but feels a little sloppy to me.
One complicating issue is that the manipulators have state. One example of manipulator state that could be factored out of the manipulators themselves is thread-safety helpers (mutexes/semaphores), but there are other data members that logically belong to the manipulators so I don't think this problem is going away.
So I'm wondering, is there some design pattern that can provide a cleaner solution for this situation?
A factory pattern could be used with the factory offering a method taking a pointer or reference to the data, and a value (possibly enumeration) indicating the operation to be performed, it then selects the agent that can perfrom that operation and asks it to do so.
As for the states, if the agents' states are synchronised then a single state in the factory would be fine - if they are not then the factory could simply provide a method to be called in the event that anything happens that could change any agent's state and inform all the agents. Or, the agents could themselves be observers of whatever it is that causes the state changes.
As for implementing a state machine - that's also often done using a factory pattern! So you could have a factory of factories where each sub factory is also an observer. This would be almost too awesome for words.

Worth using getters and setters in DTOs? (C++)

I have to write a bunch of DTOs (Data Transfer Objects) - their sole purpose is to transfer data between client app(s) and the server app, so they have a bunch of properties, a serialize function and a deserialize function.
When I've seen DTOs they often have getters and setters, but is their any point for these types of class? I did wonder if I'd ever put validation or do calculations in the methods, but I'm thinking probably not as that seems to go beyond the scope of their purpose.
At the server end, the business layer deals with logic, and in the client the DTOs will just be used in view models (and to send data to the server).
Assuming I'm going about all of this correctly, what do people think?
Thanks!
EDIT: AND if so, would their be any issue with putting the get / set implementation in the class definition? Saves repeating everything in the cpp file...
If you have a class whose explicit purpose is just to store it's member variables in one place, you may as well just make them all public.
The object would likely not require destructor (you only need a destructor if you need to cleanup resources, e.g. pointers, but if you're serializing a pointer, you're just asking for trouble). It's probably nice to have some syntax sugars constructors, but nothing really necessary.
If the data is just a Plain Old Data (POD) object for carrying data, then it's a candidate for being a struct (fully public class).
However, depending on your design, you might want to consider adding some behavior, e.g. an .action() method, that knows how to integrate the data it is carrying to your actual Model object; as opposed to having the actual Model integrating those changes itself. In effect, the DTO can be considered part of the Controller (input) instead of part of Model (data).
In any case, in any language, a getter/setter is a sign of poor encapsulation. It is not OOP to have a getter/setter for each instance fields. Objects should be Rich, not Anemic. If you really want an Anemic Object, then skip the getter/setter and go directly to POD full-public struct; there is almost no benefit of using getter/setter over fully public struct, except that it complicates code so it might give you a higher rating if your workplace uses lines of code as a productivity metric.

Object Oriented Design - The easiest case, but I'm confused anyway!

When I wrap up some procedural code in a class (in my case c++, but that is probably not of interest here) I'm often confused about the best way to do it. With procedural code I mean something that you could easily put in an procedure and where you use the surrounding object mainly for clarity and ease of use (error handling, logging, transaction handling...).
For example, I want to write some code, that reads stuff from the database, does some calculations on it and makes some changes to the database. For being able to do this, it needs data from the caller.
How does this data get into the object the best way. Let's assume that it needs 7 Values and a list of integers.
My ideas are:
List of Parameters of the constructor
Set Functions
List of Parameters of the central function
Advantage of the first solution is that the caller has to deliver exactly what the class needs to do the job and ensures also that the data is available right after the class has been created. The object could then be stored somewhere and the central function could be triggered by the caller whenever he wants to without any further interaction with the object.
Its almost the same in the second example, but now the central function has to check if all necessary data has been delivered by the caller. And the question is if you have a single set function for every peace of data or if you have only one.
The Last solution has only the advantage, that the data has not to be stored before execution. But then it looks like a normal function call and the class approaches benefits disappear.
How do you do something like that? Are my considerations correct? I'm I missing some advantages/disadvantages?
This stuff is so simple but I couldn't find any resources on it.
Edit: I'm not talking about the database connection. I mean all the data need for the procedure to complete. For example all informations of a bookkeeping transaction.
Lets do a poll, what do you like more:
class WriteAdress {
WriteAdress(string name, string street, string city);
void Execute();
}
or
class WriteAdress {
void Execute(string name, string street, string city);
}
or
class WriteAdress {
void SetName(string Name);
void SetStreet(string Street);
void SetCity(string City);
void Execute();
}
or
class WriteAdress {
void SetData(string name, string street, string city);
void Execute();
}
Values should be data members if they need to be used by more than one member function. So a database handle is a prime example: you open the connection to the database and get the handle, then you pass it in to several functions to operate on the database, and finally close it. Depending on your circumstances you may open it directly in the constructor and close it in the destructor, or just accept it as a value in the constructor and store it for later use by the member functions.
On the other hand, values that are only used by one member function and may vary every call should remain function parameters rather than constructor parameters. If they are always the same for every invocation of the function then make them constructor parameters, or just initialize them in the constructor.
Do not do two-stage construction. Requiring that you call a bunch of setXYZ functions on a class after the constructor before you can call a member function is a bad plan. Either make the necessary values initialized in the constructor (whether directly, or from constructor parameters), or take them as function parameters. Whether or not you provide setters which can change the values after construction is a different decision, but an object should always be usable immediately after construction.
Interface design is very important but in your case what you need is to learn that worst is better.
First choose the simplest solution you have, write it now.
Then you'll see what are the flaws, so fix them.
Repeat until it's not important to fix them.
The idea is that you'll have to get experience to understand how to get directly to the "best" or better said "less worst" solution of some type of problem (that's what we call "design pattern"). To get that experience you'll have to hit problems fast, solve them and try to deeply understand why something was wrong.
That's you'll have to do each time you try something "new". Errors are not a problem if you fix them and learn from them.
You should use the constructor parameters for all values, which are necessary in any case (consider that many programming languages also support constructor overloading).
This leads to the second: Setter should be used to introduce optional parameters, or to update values.
You can also join these methods: expect necessary parameters in the constructor and then call their setter-function. This way you have to do check validity checks only once (in the setters).
Central functions should use temporary parameters only (timestamps, ..)
First off, it sounds like you are trying to do too much at once. Reading, calculating and updating are all separate operations, that themselves can probably split down further.
A technique I use when I'm thinking about the design of a method or class is to think: 'what do I want the highest-level method to ideally look like?' i.e. think about the separate components of the method and split them down. That's top-down design.
In your case, I envisaged this in my head (C#):
public static void Dostuff(...)
{
Data d = ReadDatabase(...);
d.DoCalculations(...);
UpdateDatabase(d);
}
Then do the same thing for each of those methods.
When you come to passing in parameters to your method, you need to consider whether the data you're passing in is stored or not - i.e. if your class is static (it cannot be instantiated, and is instead just a collection of methods etc) or if you make objects of the class. In other words: each object of the class has a state.
If the parameters can indeed be considered to be attributes of the class, they define its state, and should be stored as private variables with getters and setters for each, where neccessary. If the class instead has no state, it should be static and the parameters passed directly to the method.
Either way, it is common, and not considered bad practice, to have both a constructor and a few get / set functions where neccessary. It is also common to have to check the state of the object at the beginning of a method, so I wouldnt worry about that.
As you can see, it largely depends on what else you are doing in this class.
The reason you can't find many resources on this is that the 'right' answer is hugely domain-specific; it depends heavily on the specific project. The best way to find out is usually by experiment.
(For example: You're right about the advantages of the first two methods. An obvious disadvantage is the use of memory to store the data the whole time the object exists. This disadvantage doesn't matter in the least if your project needs two of these data objects; it's potentially a huge problem if you need a very large number. If it's a big live dataset, you're probably better querying for data as you need it, as implied by your third solution... but not definitely, as there are times when it's better to cache the data.)
When in doubt, do a quick test implementation with a simplest-possible interface; just writing it will frequently make it clearer what the pros and cons are for your project.
Specifically addressing your example it seems as though you are still thinking too procedurally.
You should make an object that initialises the connection to the database doing all relevant error checking. Then have a method on the object that writes the values in whatever convenient way you prefer. When the object is destroyed it should release the handle to the database. That would be the object oriented way to approach the problem.
I assume the only responsibility of your WriteAddress class is to write an address to a database or an output stream. If so, then you should not worry about getters and setters for the address details; instead, define an interface AddressDataProvider that is to be implemented by all classes with which your WriteAddress class will collaborate.
One of the methods on that interface would be GetAddressParts(), which would return an array of strings as required by WriteAddress. Any class that implements that method will need to respect this array structure.
Then, in WriteAddress, define a setter SetDataProvider(AddressDataProvider). This method will be called by the code that instantiates your WriteAddress object(s).
Finally, in your Execute() method, obtain the data that are required by calling GetAddressParts() on the "data provider" that you set and write out your address.
Notice that this design shields WriteAddress from subsidiary activities that are not strictly part of its responsibilities. So, WriteAddress does not care how the address details are retrieved; it does not even care about knowing and holding the address details. It just knows from where to get them and how to write them out.
This is obvious even in the description of this design: only two names WriteAddress and AddressDataProvider come up; there is no mention of database or how to pass the address details. This is usually an indication of high cohesion and low coupling.
I hope this helps.
You can implement each approach, they don't exclude each other, then you're going to see which are most useful.

Best way of organising load/save functions in terms of static/non-static

I have a class which defines a historical extraction on a database:
class ExtractionConfiguration
{
string ExtractionName;
time ExtractionStartTime;
time ExtractionEndTime;
// Should these functions be static/non-static?
// The load/save path is a function of ExtractionName
void SaveConfigruation();
void LoadConfiguration();
}
These ExtractionConfigurations need to be saved to/loaded from disk. What is the best way of organising the save/load functions in terms of static/non-static? To me, it is clear that SaveConfiguration() should be a member function. However with LoadConfiguration(), does it make more sense to call
ExtractionConfiguration newExtraction;
newExtraction.LoadConfiguration();
and have a temporary empty instance or make the load function static
static ExtractionConfiguration LoadConfiguration(string filename);
and just call
ExtractionConfiguration newExtraction = ExtractionConfiguration::LoadConfiguration(filename);
which feels neater to me, but breaks the 'symmetry' of the load/save mechanism (is this even a meaningful/worthwhile consideration?).
I suppose asking for the 'best' answer is somewhat naive. I am really trying to get a better understanding of the issues involved here.
P.S. This is my first question on SO, so if I have not presented it correctly, please let me know and I will try and make the problem clearer.
You should consider using Boost.Serialization style serialization function that avoids having separate functions for saving and loading (even if you don't use the library itself).
In this approach you can pass the function any type of object that has operator&, to perform an operation on all the member variables. One such object might save the data to a file, another might load from a file, third might print the data on console (for debugging, etc).
If you wish to keep separate functions, having them as non-static members might be a better option. For the saving function this is obvious, but loading is a different matter because there you need to construct the object. However, quite commonly loading is done by default-constructing and then calling the load non-static member function, for symmetry reasons, I guess.
Having the loading as a function that returns a new object seems better in some ways, but then you need to decide how it returns the object. Is it allocated by new, or simply returned by value? Returning by value requires the object to be copyable and returning a pointer mandates the resource management scheme (cannot just store the object on stack).