views:

3835

answers:

11

Say I have a class that's meant to perform a single function. After performing the function, it can be destroyed. Is there any reason to prefer one of these approaches?

// Initialize arguments in constructor
MyClass myObject = new MyClass(arg1, arg2, arg3);
myObject.myMethod();

// Pass arguments to method
MyClass myObject = new MyClass();
myObject.myMethod(arg1, arg2, arg3);

// Pass arguments to static method
MyClass.myMethod(arg1, arg2, arg3);

EDIT: I was being intentionally vague about the details, to try to get guidelines for different situations. But I didn't really have in mind simple library functions like Math.random(). I'm thinking more of classes that perform some specific, complex task, but only require one (public) method to do it.

+39  A: 

I prefer the static way. Since the Class is not representing an object of any sorts it doesn't make sense to make an instance of it.

Classes that only exist for their methods should be left static.

jjnguy
+2  A: 

Can your class be made static?

If so, then I'd make it a 'Utilities' class that I would put all my one-function classes in.

Robert
I somewhat disagree. In projects I'm involved with, your Utilities class could have hundreds of unrelated methods in it.
Paul Tomblin
@Paul: Generally agreed. I hate to see classes with dozens (or yes, hundreds) of totally unrelated methods. If one must take this approach, at least split these into smaller, related sets of utilities (EG, FooUtilities, BarUtilities, etc).
John Rudy
one class- one resposibility.
Andreas Petersson
+4  A: 

If there is no reason to have an instance of the class created in order to execute the function then use the static implementation. Why make the consumers of this class create an instance when one is not needed.

Ray Jezek
+2  A: 

I really don't know what the situation is here, but I would look at putting it as a method in one of the classes that arg1,arg2 or arg3 belong to -- If you can semantically say that one of those classes would own the method.

chris
+3  A: 

I would say the Static Method format would be the better option. And I would make the class static as well, that way you wouldn't have to worry about accidentally creating an instance of the class.

Nathen Silver
+1  A: 

If you don't need to save the state of the object, then there's no need to instantiate it in the first place. I'd go with the single static method that you pass parameters to.

I'd also warn against a giant Utils class that has dozens of unrelated static methods. This can get disorganized and unwieldy in a hurry. It's better to have many classes, each with few, related methods.

Bill the Lizard
A: 

I would just do evrything in the ctor. like so:

new MyClass(arg1, arg2, arg3);// the ctor does everyhing.

or MyClass my_object(arg1, arg2, arg3);

What if you need to return anything besides an object of type MyClass?
Bill the Lizard
I consider it bad practice to put execution logic in a constructor. Good development is about semantics. Semantically, a constructor exists to construct an object, not to perform other tasks.
mstrobl
bill, if you need return value, pass reference to the ret vvalue:MyClass myObject(arg1, arg2, arg3,retvalue);mstrobl,if the object is not needed, why create it? and this trick can actualy help you in some instances.
If an object has no state, i.e. no vars, then instancing it will *not* produce any allocation - neither on heap nor stack. You can think of objects in C++ as just C function calls with a hidden first parameter pointing to a struct.
mstrobl
mstrobl, it like a c function on steroids because you can define private functions that the ctor can use. you can also use the class member variables to help pass data to the private functions.
Your argument was that if you would not need an object, "why create it". As you are talking of state, you are talking of needing an object.Using a constructor for anything other than constructing is a hack imho. Think functors. If you need to use an object implicitly, do so: MyClass().foo()
mstrobl
A: 

If this method is stateless and you don't need to pass it around, then it makes the most sense to define it as static. If you DO need to pass the method around, you might consider using a delegate rather than one of your other proposed approaches.

Joel Wietelmann
+29  A: 

I used to love utility classes filled up with static methods. They made a great consolidation of helper methods that would otherwise lie around causing redundancy and maintenance hell. They're very easy to use, no instantiation, no disposal, just fire'n'forget. I guess this was my first unwitting attempt at creating a service oriented architecture - lots of stateless services that just did their job and nothing else. As a system grows however, dragons be coming.

Polymorphism
Say we have the method UtilityClass.SomeMethod that happily buzzes along. Suddenly we need to change the functionality slightly. Most of the functionality is the same, but we have to change a couple of parts nonetheless. Had it not been a static method, we could make a derivate class and change the method contents as needed. As it's a static method, we can't. Sure, if we just need to add functionality either before or after the old method, we can create a new class and call the old one inside of it - but that's just gross.

Interface woes
Static methods cannot be defined through interfaces for logic reasons. And since we can't override static methods, static classes are useless when we need to pass them around by their interface. This renders us unable to use static classes as part of a strategy pattern. We might patch some issues up by passing delegates instead of interfaces.

Testing
This basically goes hand in hand with the interface woes mentioned above. As our ability of interchanging implementations is very limited, we'll also have trouble replacing production code with test code. Again, we can wrap them up but it'll require us to change large parts of our code just to be able to accept wrappers instead of the actual objects.

Fosters blobs
As static methods are usually used as utility methods and utility methods usually will have different purposes, we'll quickly end up with a large class filled up with non-coherent functionality - ideally, each class should have a single purpose within the system. I'd much rather have a five times the classes as long as their purposes are well defined.

Parameter creep
To begin with, that little cute and innocent static method might take a single parameter. As functionality grows, a couple of new parameters are added. Soon further parameters are added that are optional, so we create overloads of the method (or just add default values, in languages that support them). Before long, we have a method that takes 10 parameters. Only the first three are really required, parameters 4-7 are optional. But if parameter 6 is specified, 7-9 are required to be filled in as well... Had we created a class with the single purpose of doing what this static method did, we could solve this by taking in the required parameters in the constructor, and allowing the user to set optional values through properties, or methods to set multiple interdependent values at the same time. Also, if a method has grown to this amount of complexity, it most likely needs to be in its own class anyways.

Demanding consumers to create an instance of classes for no reason
One of the most common arguments is, why demand that consumers of our class create an instance for invoking this single method, while having no use for the instance afterwards? Creating an instance of a class is a very very cheap operation in most languages, so speed is not an issue. Adding an extra line of code to the consumer is a low cost for laying the foundation of a much more maintainable solution in the future. And finally, if you want to avoid creating instances, simply create a singleton wrapper of your class that allows for easy reuse - although this does make the requirement that your class is stateless. If it's not stateless, you can still create static wrapper methods that handle everything, while still giving you all the benefits in the long run. Finally, you could also make a class that hides the instantiation as if it was a singleton: MyWrapper.Instance is a property that just returns new MyClass();

Only a Sith deals in absolutes
Of course, there are exceptions to my dislike of static methods. True utility classes that do not pose any risk to bloat are excellent cases for static methods - System.Convert as an example. If your project is a one-off with no requirements for future maintenance, the overall architecture really isn't very important - static or non static, doesn't really matter - development speed does, however.

Standards, standards, standards!
Using instance methods does not inhibit you from also using static methods, and vice versa. As long as there's reasoning behind the differentiation and it's standardised. There's nothing worse than looking over a business layer sprawling with different implementation methods.

Mark S. Rasmussen
+1 for being right.
Gabe Moothart
A: 

I'd suggest that its hard to answer based on the information provided.

My gut is that if you are just going to have one method, and that you are going to throw the class away immediately, then make it a static class that takes all the parameters.

Of course, its hard to tell exactly why you need to create a single class just for this one method. Is it the typical "Utilities class" situation as most are assuming? Or are you implementing some sort of rule class, of which there might be more in the future.

For instance, have that class be plugable. Then you'd want to create an Interface for your one method, and then you'd want to have all the parameters passed into the interface, rather than into the constructor, but you wouldn't want it to be static.

Nick
A: 

For simple applications and internal helpers, I would use a static method. For applications with components, I'm loving the Managed Extensibility Framework. Here's an excerpt from a document I'm writing to describe the patterns you'll find across my APIs.

  • Services
    • Defined by an I[ServiceName]Service interface.
    • Exported and imported by the interface type.
    • The single implementation is provided by the host application and consumed internally and/or by extensions.
    • The methods on the service interface are thread-safe.

As a contrived example:

public interface ISettingsService
{
    string ReadSetting(string name);

    void WriteSetting(string name, string value);
}

[Export]
public class ObjectRequiringSettings
{
    [Import]
    private ISettingsService SettingsService
    {
        get;
        set;
    }

    private void Foo()
    {
        if (SettingsService.ReadSetting("PerformFooAction") == bool.TrueString)
        {
            // whatever
        }
    }
}
280Z28