2

I'm wondering about functions used like this:

object1->objectMethod1(arg1, arg2);

if objectMethod1:
- does not change the object state
- does not use the object's state at all
- is used by the class extensively
- logically fits as being used by the class

should it be made into a member function?

example:

class CSVFile {
private:
  filestream stream
  string header
  int num_columns
public:
  CSVFile(string filename)
  CSVFile() throws DefaultConstructorException()
...
CSVFile::initHeader() {
  header = stream.getLine()
  assert(isInCSVFormat(header)) <-- that

should isInCSVFormat(string) be a member function or not?

1

I would answer this by considering dependencies. I assume your class depends on this function, so what else does?

If no other class does, then yes, it should be packaged with the class. You might even make it private. Whether it is a static method, or in a static class or in a namespace depends on the implementation language and local coding conventions.

If other classes depend on it but only when using your class, then it should probably still be packaged with the class.

If other classes depend on it for uses other than related to using your class, then it should packaged separately.

You should also consider whether this function brings in its own dependencies. If the function brings in a whole additional library with its own dependencies then it might better to keep it separate, regardless of the above.

2

The usual argument against what you call class functions (some languages use the static keyword for these) is that they are not easily mockable, and are therefore not testable. But that's an argument for making your class functions pure, not avoiding making them at all. Class functions do not require a mock for the same reasons that they do not require an object instantiation.

Since you've already established that the class functions you are writing are going to be pure (by virtue of the conditions you have placed on them, like not changing state and not causing side-effects), I regard this as a perfectly sensible use case for them.

Class methods are especially useful as factory methods.

1

Given those criteria, no. The fact that it does not access the object's private fields means it's not an essential part of your abstraction. Keeping such functions out of your class is better for encapsulation - you're limiting the amount of code that could potentially be affected by a change in the implementation. See this article.

Moreover, there's an unlimited number of ways you might use your class. If you shove a new function in there every time you find a common way to use it, the class will grow indefinitely. In a language like C++, you'd have to recompile everything that included the header file of your class.

  • 1. Not all methods in the class need to be public, only the useful ones. 2. The method should have something to do with the class, otherwise it should go into a utility class. It doesn't have to touch state to be relevant to the class' purpose. – Robert Harvey Mar 21 '14 at 20:26
  • @Doval: So such functions that do not use private fields in any way should, instead, be declared and defined as functions in the main line? – user2738698 Mar 21 '14 at 20:28
  • @RobertHarvey Regarding point 1, I'm assuming he's asking about public functions - if the function in question is going to be private to the class, it doesn't really matter if it's static or not. Regarding point 2, can you give an example of a function that only needs access to the class's public interface but you feel should belong in the class? – Doval Mar 21 '14 at 20:37
  • A Factory Method. Well, I supposed you do have to touch state, but all of the state being touched will happen inside the method itself, in the process of creating the object; it's completely encapsulated. If you write the class constructors properly, you still may not need to touch internal state. – Robert Harvey Mar 21 '14 at 20:39
0

To keep things simpler and easier to understand, I try to reduce the number of features that my code uses (or could potentially use). If that subroutine is not going to need to be dynamically dispatched (for polymorphism or inheritance) then it should not be a member function and is perhaps better off as just a static method. If in addition to that you also don't need to access any private variables then you can safely put that subroutine in a totally separate class.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.