Using getter/setter vs "tell, don't ask"? - c++

Tell, don't ask principle here is often pasted to me when I use getters or setters, and people tell me not to use them.
The site clearly explains what I should and what I shouldn't do, but it doesn't really explain WHY I should tell, instead of asking.
I find using getters and setters much more efficient, and I can do more with them.
Imagine a class Warrior with attributes health and armor:
class Warrior {
unsigned int m_health;
unsigned int m_armor;
};
Now someone attacks my warrior with a special attack that reduces his armor for 5 seconds. Using setter's it would be like this:
void Attacker::attack(Warrior *target)
{
target->setHealth(target->getHealth() - m_damage);
target->setArmor(target->getArmor() - 20);
// wait 5 seconds
target->setArmor(target->getArmor() + 20);
}
And with tell, don't ask principle it would look like this (correct me if i'm wrong):
void Attacker::attack(Warrior *target)
{
target->hurt(m_damage);
target->reduceArmor(20);
// wait 5 seconds
target->increaseArmor(20);
}
Now the second one obviously looks better, but I can't find the real benefits of this.
You still need the same amount of methods (increase/decrease vs set/get) and you lose the benefit of asking if you ever need to ask.
For example, how would you set warriors health to 100?
How do you figure out whether you should use heal or hurt, and how much health you need to heal or hurt?
Also, I see setters and getters being used by some of the best programmers in the world.
Most APIs use it, and it's being used in the std lib all the time:
for (i = 0; i < vector.size(); i++) {
my_func(i);
}
// vs.
vector.execForElements(my_func);
And if I have to decide whether to believe people here linking me one article about telling, not asking, or to believe 90% of the large companies (apple, microsoft, android, most of the games, etc. etc.) who have successfully made a lot of money and working programs, it's kinda hard for me to understand why would tell, don't ask be a good principle.
Why should I use it (should I?) when everything seems easier with getters and setters?

You still need the same amount of methods (increase/decrease vs set/get) and you lose the benefit of asking if you ever need to ask.
You got it wrong. The point is to replace the getVariable and setVariable with a meaningful operation: inflictDamage, for example. Replacing getVariable with increaseVariable just gives you different more obscure names for the getter and setter.
Where does this matter. For example, you don't need to provide a setter/getter to track the armor and health differently, a single inflictDamage can be processed by the class by trying to block (and damaging the shield in the process) and then taking damage on the character if the shield is not sufficient or your algorithm demands it. At the same time you can add more complex logic in a single place.
Add a magic shield that will temporarily increase the damage caused by your weapons for a short time when taking damage, for example. If you have getter/setters all attackers need to see if you have such an item, then apply the same logic in multiple places to hopefully get to the same result. In the tell approach attackers still need to just figure out how much damage they do, and tell it to your character. The character can then figure out how the damage is spread across the items, and whether it affects the character in any other way.
Complicate the game and add fire weapons, then you can have inflictFireDamage (or pass the fire damage as a different argument to the inflictDamage function). The Warrior can figure out whether she is affected by a fire resistance spell and ignore the fire damage, rather than having all other objects in the program try to figure out how their action is going to affect the others.

Well, if that's so, why bother with getters and setters after all? You can just have public fields.
void Attacker::attack(Warrior *target)
{
target->health -= m_damage;
target->armor -= 20;
// wait 5 seconds
target->armor += 20;
}
The reason is simple here. Encapsulation. If you have setters and getters, it's no better than public field. You don't create a struct here. You create a proper member of your program with defined semantics.
Quoting the article:
The biggest danger here is that by asking for data from an object, you
are only getting data. You’re not getting an object—not in the large
sense. Even if the thing you received from a query is an object
structurally (e.g., a String) it is no longer an object semantically.
It no longer has any association with its owner object. Just because
you got a string whose contents was “RED”, you can’t ask the string
what that means. Is it the owners last name? The color of the car? The
current condition of the tachometer? An object knows these things,
data does not.
The article here suggests here that "tell, don't ask" is better here because you can't do things that make no sense.
target->setHealth(target->getArmor() - m_damage);
It doesn't make sense here, because the armor has nothing in relation to health.
Also, you got it wrong with std lib here. Getters and setters are only used in std::complex and that's because of language lacking functionality (C++ hadn't had references then). It's the opposite, actually. C++ standard library encourages usage of algorithms, to tell the things to do on containers.
std::for_each(begin(v), end(v), my_func);
std::copy(begin(v), end(v), begin(u));

One reason that comes to mind is the ability to decide where you want the control to be.
For example, with your setter/getter example, the caller can change the Warrior's health arbitrarily. At best, your setter might enforce maximum and minimum values to ensure the health remains valid. But if you use the "tell" form you can enforce additional rules. You might not allow more than a certain amount of damage or healing at once, and so on.
Using this form gives you much greater control over the Warrior's interface: you can define the operations that are permitted, and you can change their implementation without having to rewrite all the code that calls them.

At my point of view, both codes do the same thing. The difference is in the expressivity of each one. The first one (setters anad getters) can be more expressive than the second one (tell, don' ask).
It's true that, when you ask, you are going to make a decision. But it not happens in most part of times. Sometimes you just want to know or set some value of the object, and this is not possible with tell, don't ask.
Of course, when you create a program, it's important to define the responsabilities of an object and make sure that these responsabilities remains only inside the object, letting the logic of your application out of it. This we already know, but if you need ask to make a decision that's not a responsability of your object, how do you make it with tell, don't ask?
Actually, getters and setters prevails, but it's common to see the idea of tell, don't ask together with it. In other words, some APIs has getters and setters and also the methods of the tell, don't ask idea.

Related

C++ member variable change listeners (100+ classes)

I am trying to make an architecture for a MMO game and I can't figure out how I can store as many variables as I need in GameObjects without having a lot of calls to send them on a wire at the same time I update them.
What I have now is:
Game::ChangePosition(Vector3 newPos) {
gameobject.ChangePosition(newPos);
SendOnWireNEWPOSITION(gameobject.id, newPos);
}
It makes the code rubbish, hard to maintain, understand, extend. So think of a Champion example:
I would have to make a lot of functions for each variable. And this is just the generalisation for this Champion, I might have have 1-2 other member variable for each Champion type/"class".
It would be perfect if I would be able to have OnPropertyChange from .NET or something similar. The architecture I am trying to guess would work nicely is if I had something similar to:
For HP: when I update it, automatically call SendFloatOnWire("HP", hp);
For Position: when I update it, automatically call SendVector3OnWire("Position", Position)
For Name: when I update it, automatically call SendSOnWire("Name", Name);
What are exactly SendFloatOnWire, SendVector3OnWire, SendSOnWire ? Functions that serialize those types in a char buffer.
OR METHOD 2 (Preffered), but might be expensive
Update Hp, Position normally and then every Network Thread tick scan all GameObject instances on the server for the changed variables and send those.
How would that be implemented on a high scale game server and what are my options? Any useful book for such cases?
Would macros turn out to be useful? I think I was explosed to some source code of something similar and I think it used macros.
Thank you in advance.
EDIT: I think I've found a solution, but I don't know how robust it actually is. I am going to have a go at it and see where I stand afterwards. https://developer.valvesoftware.com/wiki/Networking_Entities
On method 1:
Such an approach could be relatively "easy" to implement using a maps, that are accessed via getters/setters. The general idea would be something like:
class GameCharacter {
map<string, int> myints;
// same for doubles, floats, strings
public:
GameCharacter() {
myints["HP"]=100;
myints["FP"]=50;
}
int getInt(string fld) { return myints[fld]; };
void setInt(string fld, int val) { myints[fld]=val; sendIntOnWire(fld,val); }
};
Online demo
If you prefer to keep the properties in your class, you'd go for a map to pointers or member pointers instead of values. At construction you'd then initialize the map with the relevant pointers. If you decide to change the member variable you should however always go via the setter.
You could even go further and abstract your Champion by making it just a collection of properties and behaviors, that would be accessed via the map. This component architecture is exposed by Mike McShaffry in Game Coding Complete (a must read book for any game developer). There's a community site for the book with some source code to download. You may have a look at the actor.h and actor.cpp file. Nevertheless, I really recommend to read the full explanations in the book.
The advantage of componentization is that you could embed your network forwarding logic in the base class of all properties: this could simplify your code by an order of magnitude.
On method 2:
I think the base idea is perfectly suitable, except that a complete analysis (or worse, transmission) of all objects would be an overkill.
A nice alternative would be have a marker that is set when a change is done and is reset when the change is transmitted. If you transmit marked objects (and perhaps only marked properties of those), you would minimize workload of your synchronization thread, and reduce network overhead by pooling transmission of several changes affecting the same object.
Overall conclusion I arrived at: Having another call after I update the position, is not that bad. It is a line of code longer, but it is better for different motives:
It is explicit. You know exactly what's happening.
You don't slow down the code by making all kinds of hacks to get it working.
You don't use extra memory.
Methods I've tried:
Having maps for each type, as suggest by #Christophe. The major drawback of it was that it wasn't error prone. You could've had HP and Hp declared in the same map and it could've added another layer of problems and frustrations, such as declaring maps for each type and then preceding every variable with the mapname.
Using something SIMILAR to valve's engine: It created a separate class for each networking variable you wanted. Then, it used a template to wrap up the basic types you declared (int, float, bool) and also extended operators for that template. It used way too much memory and extra calls for basic functionality.
Using a data mapper that added pointers for each variable in the constructor, and then sent them with an offset. I left the project prematurely when I realised the code started to be confusing and hard to maintain.
Using a struct that is sent every time something changes, manually. This is easily done by using protobuf. Extending structs is also easy.
Every tick, generate a new struct with the data for the classes and send it. This keeps very important stuff always up to date, but eats a lot of bandwidth.
Use reflection with help from boost. It wasn't a great solution.
After all, I went with using a mix of 4, and 5. And now I am implementing it in my game. One huge advantage of protobuf is the capability of generating structs from a .proto file, while also offering serialisation for the struct for you. It is blazingly fast.
For those special named variables that appear in subclasses, I have another struct made. Alternatively, with help from protobuf I could have an array of properties that are as simple as: ENUM_KEY_BYTE VALUE. Where ENUM_KEY_BYTE is just a byte that references a enum to properties such as IS_FLYING, IS_UP, IS_POISONED, and VALUE is a string.
The most important thing I've learned from this is to have as much serialization as possible. It is better to use more CPU on both ends than to have more Input&Output.
If anyone has any questions, comment and I will do my best helping you out.
ioanb7

C++ Why should I use get and set functions when working with classes [duplicate]

This question already has answers here:
Why use getters and setters/accessors?
(37 answers)
Closed 9 years ago.
I've been told not to make my variables public inside a class. I should always make a get and a set function. For example :
class Whatever
{
public:
void setSentence(const std::string &str) { sentence = str; }
void setAnInteger(const int integer) { anInteger = integer; }
std::string getSentence() { return sentence; }
int getAnInteger() { return anInteger; }
private:
std::string sentence;
int anInteger;
};
Why should I do that? Isn't just simply using those variables more convenient? Also, is that a good c++ programming style?
The main reason is to increase encapsulation. If your class exposes those member variables, many functions in your client code will have a dependency towards those variables.
Suppose one day you want want to change the name of those variables, or you want to change the implementation of your class so that the type and number of member variables would be different than the current one: how many functions would be affected by this change? How many functions would you have to re-write (at least in part)?
Right, potentially infinite. You just can't count them all. On the other hand, if you have getters and setters, only those 4 functions will have access to the internal representation of your class. Changing the internal representation won't require any change to the code of your client functions; only those 4 member functions may have to be changed.
In general, encapsulation makes your life easier with respect to future changes. At a certain point in time you may want to log a message every time a certain property is set. You may want to fire an event every time a certain property is set. You may want to compute a certain value on the fly rather than reading it each time from a cache data member, or read it from a database, or whatever.
Having getters and setters allow you to implement any of those changes without requiring to change the client code.
As far as general design philosophy is concerned, there is no "always" or "never" when it comes to implementing accessors versus not implementing accessors that the community as a whole agrees on.
Many will advise you to make all data members private and provide accessors & mutators. Always.
Others will tell you to make data members private if changing them from client code is undesirable, and leave them public otherwise.
Yet others will tell you that classes shouldn't have more than one or so data member at all, and all the data should be encapsulated in yet another object, preferably a struct.
You have to decide for yourself which is right, keeping in mind that this will depend not only on your approach, but also that of the organization for which you work.
If you ask me, my preference is to make everything public until I have a reason not to. Simple. But that's just me.
You write explicit getters and setters as a sane plan for future development. If your class' users are directly accessing its members and you need to change the class in a way that is incompatible with that habit, you have to change every chunk of code that interfaces with you in this way. If you write a getter and setter, the compiler will optimize it to be time-equivalent to direct access (if that is all it does) and you can later change the logic if you need to - without having to change a ton of other code.
When you make get or set method and use it 40 times in your code, you can handle future changes more easily.
Imagine, that you use public variable and use it 40 times in your code. After a month of developing your program, you'll come up with a great idea: What if I divide this variable by 1000 and so I would have better values to calculate with!
Wow, great, but now I have to find every single line, where I use it and change it. If I only had a get method :(
That's the main reason of getters and setters, even if they are very simple, it's better to have it. You will thank yourself once.
Data encapsulation is one of the major principles of OOP. It is the process of combining data and functions into a single unit called class. Using the method of encapsulation, the programmer cannot directly access the data. Data is only accessible through the functions existing inside the class so that the implementation details of a class that are hidden from the user. It's to protect both the caller and the function from accidentally changing the behavior of a method, or from needing to know how a method works.
The textbook-ish answer recalled from me taking the first OOP class was: Get and set methods are used to wrap around private variables. Usually people compare between having get and set or just simply set those variables to be public; in this case, get and set approach is good because it protects those variables from being modified accidentally due to bugs and etc..
People (me when I took that class) might ask "isn't get and set also modify those variables, if so, how is that different than being modified as a public variable".
The rationale is: to have get and set function, you are asking the user or yourself to explicitly specify they want to modify the variable by calling those functions. Without calling those functions, the private variables will be less likely (still possible depends on implementation) modified unwillingly or accidentally.
In short, you should not do that.
In general, I suggest to read Fowler's Refactoring, then you will have a picture what gets hindered by having naked data, and what kind of access aligns well. And importantly whether the whole thing applies to your cases or not.
And as you know pros&cons you can safely ignore "should do/don't" stuff like at start of this answer or others.

How should I decide whether to build a "protected interface"?

From: http://www.parashift.com/c++-faq-lite/basics-of-inheritance.html#faq-19.9
Three keys: ROI, ROI and ROI.
Every interface you build has a cost and a benefit. Every reusable
component you build has a cost and a benefit. Every test case, every
cleanly structured thing-a-ma-bob, every investment of any sort. You
should never invest any time or any money in any thing if there is not
a positive return on that investment. If it costs your company more
than it saves, don't do it!
Not everyone agrees with me on this; they have a right to be wrong.
For example, people who live sufficiently far from the real world act
like every investment is good. After all, they reason, if you wait
long enough, it might someday save somebody some time. Maybe. We hope.
That whole line of reasoning is unprofessional and irresponsible. You
don't have infinite time, so invest it wisely. Sure, if you live in an
ivory tower, you don't have to worry about those pesky things called
"schedules" or "customers." But in the real world, you work within a
schedule, and you must therefore invest your time only where you'll
get good pay-back.
Back to the original question: when should you invest time in building
a protected interface? Answer: when you get a good return on that
investment. If it's going to cost you an hour, make sure it saves
somebody more than an hour, and make sure the savings isn't "someday
over the rainbow." If you can save an hour within the current project,
it's a no-brainer: go for it. If it's going to save some other project
an hour someday maybe we hope, then don't do it. And if it's in
between, your answer will depend on exactly how your company trades
off the future against the present.
The point is simple: do not do something that could damage your
schedule. (Or if you do, make sure you never work with me; I'll have
your head on a platter.) Investing is good if there's a pay-back for
that investment. Don't be naive and childish; grow up and realize that
some investments are bad because they, in balance, cost more than they
return.
Well, I didn't understand how to correlate this to C++ protected interface.
Please give any real C++ examples to show what this FAQ is talking about.
First off, do not ever treat any programming reference as definitive. Ever. Everything is somebody's opinion, and in the end you should do what works best for you.
So, that said, what this text is basically trying to say is "don't use techniques that cost you more time than they save". One example of the "protected interface" they're describing is the following:
class C {
public:
int x;
};
Now, in Java, all the Java EE programming books will tell you to always implement that class like this:
class C {
public:
int getX() { return x; }
void setX(int x) { this.x = x; }
private:
int x;
};
... that's an implementation of proper encapsulation (technical term: simplifying a little, it means minimizing sharing between discrete parts). The classes using your code are concerned that you have some way to get and set an integer, not that it's actually stored as an int inside the class. So if you use accessor methods, you're better able to change the underlying implementation later: maybe you want it to read that variable from the network?
However, that was a large amount of extra code (in terms of characters) and some extra complexity to implement that. Doing things properly actually has a cost! It's not a cost in terms of correctness of the code - directly - but you spent some number of minutes doing it "better" that you could have spent doing something else, and there is a nonzero amount of work involved in maintaining everything you write, no matter how trivial.
So, what is being said in this passage is in my mind good advice: always double-check that when you go to do something, you're going to get more out of it than what you put in. Sanity check that you are not following an ideal to the detriment of your actual effectiveness as a programmer or a human being.
That's advice that will serve you well in any programming language, and in any walk of life.
From your quote above, the guy sounds like a pedantic jerk :)
Looking at the previous entries in his FAQ, he's really saying the following:
1) A class has two distinct interfaces for two distinct sets of clients:
It has a public interface that serves unrelated classes
It has a protected interface that serves derived classes
2) Should you always go to the trouble of creating two different interfaces for each class?
3) Answer: "no, not necessarily"
Sometimes it's worth the extra effort to create protected getter and setter methods, and make all data "private"
Other times - he says - it's "good enough" to make the data itself "protected". Without doing all the extra work of writing a bunch of extra code, and incurring the consequent size and performance penalties.
Sounds reasonable to me. Do what you need to do - but don't go overboard and do a bunch of unnecessary stuff in the name of "theory".
That's all he's saying - use good judgement, and don't go overboard.
You can't argue with that :)
PS:
FAQ's 19.5 through 19.9 in your link deal with "derived classes". None of this discussion is relevant outside of the question "how should I structure base classes for inheritance?" In other words, it's not a discussion about "classes" in general - only about "how should a super class best make things visible to it's subclasses?".

Examples of why declaring data in a class as private is important?

I understand that only the class can access the data so therefore it is "safer" and what not but I don't really understand why it is such a big deal. Maybe it is because I haven't made any programs complex enough where data could accidentally be changed but it just a bit confusing when learning classes and being told that making things private is important because it is "safer" when the only time I have changed data in a program is when I have explicitly meant to. Could anyone provide some examples where data would have been unintentionally changed had that data not been private?
Depends what you mean by "unintentional changes". All code is written by someone so if he is changing a member variable of a class then the change is intentional (at least from his side). However the implementor of the class might not have expected this and it can break the functionality.
Imagine a very simple stack:
class Stack
{
public:
int Items[10];
int CurrentItemIndex;
}
Now CurrentItemIndex points to the index which represents the current item on top of the stack. If someone goes ahead and changes it then your stack is corrupted. Similarly someone can just write stuff into Items. If something is public then it is usually a sign that it is intended for public usage.
Also making members private provides encapsulation of the implementation details. Imagine someone iterates over stack on the above implementation by examining Items. Then it will break all code if the implementation of the stack gets changed to be a linked list to allow arbitrary number of items. In the end the maintenance will kill you.
The public interface of a class should always be as stable as possible because that's what people will be using. You do not want to touch x lines of code using a class just because you changed some little detail.
The moment you start collaborating with other people on code, you'll appreciate the clarity and security of keeping your privates private.
Say you've designed a class that rotates an image. The constructor takes an image object, and there's a "rotate" method that will rotate the image the requested number of degrees and return it.
During rotation, you keep member variables with the state of the image, say for example a map of the pixels in the image itself.
Your colleagues begin to use the class, and you're responsible for keeping it working. After a few months, someone points out to you a technique that performs the manipulations more efficiently without keeping a map of the pixels.
Did you minimize your exposed interface by keeping your privates private?
If you did, you can swap out the internal implementation to use on the other technique, and the people who've been depending on your code won't need to make any changes.
If you didn't, you have no idea what bits of your internal state your colleagues are depending on, and you can't safely make any changes without contacting all of your colleagues and potentially asking them to change their code, or changing their code for them.
Is this a problem when you're working alone? Maybe not. But it is a problem when you've got an employer, or when you want to open-source that cool new library you're so proud of.
When you make a library that other people use, you want to show the most basic sub-set of your code possible to allow external code to interface with it. This is called information hiding. It would cause more issues if other developers were allowed to modify any field they wanted, perhaps in an attempt of performing some task. An attempt that would cause unspecified program behaviour.
Generally you want to hide "data" (make vars private) so when people that aren't familiar with the class don't access data directly. Instead if they use Public modifiers to access and change that data.
Eg. accessing name via public setter could check for any problems and also make first character upper case
Accessing data directly will not do those checks and possible changes.
You don't want someone to suddenly fiddle with your internals, no? So do C++'s classes.
The problem is, if anyone can suddenly change the state of a variable that is yours, your class will screw up. It's as if someone suddenly fills your gut with something you don't want. Or exchanges your lung for someone elses.
Let's say you have a BankAccount class where you store a person's NIP and cash amount. Let's put all the fields public and see what could go wrong:
class BankAccount
{
public:
std::string NIP;
int cash;
};
Now, let's pretend that you leave it this way and use it throughout your program. Later on, you find a nasty bug caused by a negative amount of cash (whether it is from calculations or simply an accident). So you spend a couple of hours finding where that negative amount came from and fix it.
You don't want this to happen again, so you decide to put the cash amount private and perform checks before setting the cash amount to avoid any other bugs like the previous one. So you go like this:
class BankAccount
{
public:
int getCash() const { return cash; }
void setCash(int amount)
{
if (amount >= 0)
cash = amount;
else
throw std::runtime_exception("Cash amount is negative.");
}
private:
int cash;
}
Now what? You have to find all the cash references and replace them. A quick and dirty Find and Replace won't fix it so easily: you must change accessors to getCash() and setters to setCash. All this time fixing something not so important that could have been avoided by hiding the implementation details within your class and only giving access to the general interface.
Sure, that's indeed a pretty dumb example, but it happened to me so many times with more complex cases(sometimes the bug is much harder to find) that I've really learned to encapsulate as much as I can. Do your future-self and the viewers of your code a favor and hide private members, you never know when your "implementation details" will change.
When you are on a project where 2 or more people are working on the same project, but you work lets, say, 2 people work on Mondays, 2 on Tuesdays, 2 on Wednesdays, etc. The next people that will continue the project won't have to go bother the other coders just to explain what/when/why it has been that way. If you know TORTOISE you will see it's very helpful.

Is it a good practice to write classes that typically have only one public method exposed?

The more I get into writing unit tests the more often I find myself writing smaller and smaller classes. The classes are so small now that many of them have only one public method on them that is tied to an interface. The tests then go directly against that public method and are fairly small (sometimes that public method will call out to internal private methods within the class). I then use an IOC container to manage the instantiation of these lightweight classes because there are so many of them.
Is this typical of trying to do things in a more of a TDD manner? I fear that I have now refactored a legacy 3,000 line class that had one method in it into something that is also difficult to maintain on the other side of the spectrum because there is now literally about 100 different class files.
Is what I am doing going too far? I am trying to follow the single responsibility principle with this approach but I may be treading into something that is an anemic class structure where I do not have very intelligent "business objects".
This multitude of small classes would drive me nuts. With this design style it becomes really hard to figure out where the real work gets done. I am not a fan of having a ton of interfaces each with a corresponding implementation class, either. Having lots of "IWidget" and "WidgetImpl" pairings is a code smell in my book.
Breaking up a 3,000 line class into smaller pieces is great and commendable. Remember the goal, though: it's to make the code easier to read and easier to work with. If you end up with 30 classes and interfaces you've likely just created a different type of monster. Now you have a really complicated class design. It takes a lot of mental effort to keep that many classes straight in your head. And with lots of small classes you lose the very useful ability to open up a couple of key files, pick out the most important methods, and get an idea of what the heck is going on.
For what it's worth, though, I'm not really sold on test-driven design. Writing tests early, that's sensible. But reorganizing and restructuring your class design so it can be more easily unit tested? No thanks. I'll make interfaces only if they make architectural sense, not because I need to be able to mock up some objects so I can test my classes. That's putting the cart before the horse.
You might have gone a bit too far if you are asking this question. Having only one public method in a class isn't bad as such, if that class has a clear responsibility/function and encapsulates all logic concerning that function, even if most of it is in private methods.
When refactoring such legacy code, I usually try to identify the components in play at a high level that can be assigned distinct roles/responsibilities and separate them into their own classes. I think about which functions should be which components's responsibility and move the methods into that class.
You write a class so that instances of the class maintain state. You put this state in a class because all the state in the class is related.You have function to managed this state so that invalid permutations of state can't be set (the infamous square that has members width and height, but if width doesn't equal height it's not really a square.)
If you don't have state, you don't need a class, you could just use free functions (or in Java, static functions).
So, the question isn't "should I have one function?" but rather "what state-ful entity does my class encapsulate?"
Maybe you have one function that sets all state -- and you should make it more granular, so that, e.g., instead of having void Rectangle::setWidthAndHeight( int x, int y) you should have a setWidth and a separate setHeight.
Perhaps you have a ctor that sets things up, and a single function that doesIt, whatever "it" is. Then you have a functor, and a single doIt might make sense. E.g., class Add implements Operation { Add( int howmuch); Operand doIt(Operand rhs);}
(But then you may find that you really want something like the Visitor Pattern -- a pure functor is more likely if you have purely value objects, Visitor if they're arranged in a tree and are related to each other.)
Even if having these many small objects, single-function is the correct level of granularity, you may want something like a facade Pattern, to compose out of primitive operations, often-used complex operations.
There's no one answer. If you really have a bunch of functors, it's cool. If you're really just making each free function a class, it's foolish.
The real answer lies in answering the question, "what state am I managing, and how well do my classes model my problem domain?"
I'd be speculating if I gave a definite answer without looking at the code.
However it sounds like you're concerned and that is a definite flag for reviewing the code. The short answer to your question comes back to the definition of Simple Design. Minimal number of classes and methods is one of them. If you feel like you can take away some elements without losing the other desirable attributes, go ahead and collapse/inline them.
Some pointers to help you decide:
Do you have a good check for "Single Responsibility" ? It's deceptively difficult to get it right but is a key skill (I still don't see it like the masters). It doesn't necessarily translate to one method-classes. A good yardstick is 5-7 public methods per class. Each class could have 0-5 collaborators. Also to validate against SRP, ask the question what can drive a change into this class ? If there are multiple unrelated answers (e.g. change in the packet structure (parsing) + change in the packet contents to action map (command dispatcher) ) , maybe the class needs to be split. On the other end, if you feel that a change in the packet structure, can affect 4 different classes - you've run off the other cliff; maybe you need to combine them into a cohesive class.
If you have trouble naming the concrete implementations, maybe you don't need the interface. e.g. XXXImpl classes implmenting XXX need to be looked at. I recently learned of a naming convention, where the interface describes a Role and the implementation is named by the technology used to implement the role (or falling back to what it does). e.g. XmppAuction implements Auction (or SniperNotifier implements AuctionEventListener)
Lastly are you finding it difficult to add / modify / test existing code (e.g. test setup is long or painful ) ? Those can be signs that you need to go refactoring.