tags:

views:

104

answers:

6

Hi,

It's not as though I don't understand OOP concept, and what should be done when, but sometimes I just mentally get lost in that.

What better from an example? So I needed to download a file to a temp path, I decided to get the temp path not by the normal methods of dot net, because of irrelevant reason. So I wrote my own method for this string GetTempFileSafe(string extension, out FileStream), nice, isn't it? But hey, wait a minute, this is not the right place for this method... This method might be used for other things. It need to be a static public method somewhere. but where? Well, I guess I'll need to open a new static class for it. Hope I'll add it more methods some other day.

So I defined public static class FileStreamUtils \\one hell of a name huh?, and added to it my method. But hold on.. Where this class should be? Basically I can be use from any project... it has nothing to do with this specific one. So I opened a whole new library to which I called ItayUtils (NOT Italy - Itay. and it is just my name, don't freak out.)

I added my static class with my one single static method into it, built the library, add the dll as a reference to my original project... and that it. (pay attention the method is more difficult to debug, because I'm using the dll rather than the original code)

Now don't get me wrong. I literally love OOP concepts and tidiness, but sometimes it just mentally exhaust me.. maybe because I work all by my own.

So what do you think? Am I just crying for nothing, and things like open an utilities library are done mostly once, and I just need to change my attitude? Or do you think that sometimes it's better not to stick to neatness that much (in my case, for example, just live the method there, and in case I'll ever need it again, move it to public use)?

Thank you very much. And please, if you somehow succeed to find a reason to vote me down, no problem, but just please leave a comment, so I'll be able not to repeat my mistakes here.

+4  A: 

I'm always struck by how on point Robert Glass' Rules of Three are in these situations. Don't worry about reuse until you have three places where your function might fit. I always like to write the function the first time I need it. Note that I'm duplicating it the second time. And the third time do the work for reuse (refactor it into a utility library).

Jason Punyon
Perfect example of over-engineering.
whatnick
well it's depends on the case.. sometimes i'll made a method for something if if i 100% sure it won't be ever use again, just because it much more easy to think with small units instead of one huge unreadable method.beside, it still seems weird to me to actually copy the code.. but maybe...
Itay
A: 

To be honest what you have done is not incorrect. However what you have done and what I see alot is people panicing about how things should be done which then takes there focus off the job in hand, making a cool piece of software that does some cool function.

In your particular case you didnt need a class library as there is only one function so I'd just stick it in a Helper class. However if you plan on adding a lot of useful functions then a class library is a nice way to use the code over and over. But dont add too many layers to an application that does not need it.

Pino
A: 

My general rule of thumb is that every time I write a static method with at least one parameter, it's a code smell.

In OO, operations should be tied to objects, so instead of manipulating one or more objects from a helper library, it's better to move the method to one of the objects.

I know that's impossible if you are working with the built-in types from the BCL, but the smell should get you started thinking about alternatives.

Let's look at your example: You can't add the GetTempFile safe to either System.String nor FileStream, but do any of the parameters represent a hidden concept that would be better modeled as an object?

While I don't know if it's true in your example, but 'extension' sounds like a concept to me, so why not define an Extension class like this:

public class Extension
{
    private readonly string extension;

    public Extension(string extension)
    {
        // Guard Clauses go here
        this.extention = extension;
    }

    public string GetTempFileSafe(out FileStream)
    {
        // implementation goes here, using this.extension...
    }
}

As a next step, you could then change this API to get rid of the out parameter by encapsulating the resulting string and the FileStream in a new object.

Mark Seemann
"Extension" is hardly a place where I'd go and look for a method that created a temp file. To me what you're doing is forcing OOP on a perfectly fine standalone utility function.
Freed
@Freed: I'm not forcing anything - I'm merely trying to use an example to illustrate how rethinking utility functions into proper objects may uncover implicit concepts that are better modeled as objects.
Mark Seemann
=\ by extension i mean `.doc` or something like that. the file name is not important, but this is. about you code.... i don't know.. do you suggest create a new instance for every temp file? sound weird to me.. but maybe =\
Itay
@Mark, I say "forcing" because creating a temp file is not a natural operation for an "extension". There are cases where it's better to rewrite a utility function using OOP, this is not a good example of doing so. Have a look at File and Directory in the BCL for example, they could all have required object instances as well, but it wouldn't have made them better.
Freed
If the utility method is truly isolated, then a static method is often fine. However, when you start extracting concepts into objects, it often turns out that you have several related utility methods that actually work on the same concept. It often takes a little coercion to discover such concepts, which is why I recommend this as an exercise even when it might seem redundant at first. It often happens that once you start doing this, that class becomes a natural owner of other methods as well.
Mark Seemann
So to get a filename, you have to first create an extension object? An extension is a part (or property or attribute ) of a filename, not the other way around.
Jeanne Pindar
A: 

Apparently you're talking C# which I don't know, I'm mostly a Java person these days, so maybe there's a technical difference, but ...

In Java you can divide your classes into "packages". You can compile multiple packages at the same time, keep them together in an IDE, etc, but it's also easy to break them out.

When I write a group of classes that I think I am likely to want to re-use, I therefore put them in a separate package. I still keep them as part of the same project unless and until I actually want to use them elsewhere. If that happens, fine, I copy the package to its own project and build a library from it.

Thus during development it's still part of the same project, still in the same workspace, etc, and so is easy to debug and generally to keep track of.

If I never use it elsewhere, find, no harm done.

If I do use it elsewhere, then sometimes I'm lazy and just copy the package to the new project. Occassionally I really make it a stand-alone library. (And when I say "occassionally", I think in real life I mean I've done this twice in the last ten years.)

As I say, I don't know how C# groups things, whether there's an easy way to break a set of classes out into some convenient "unit".

Jay
A: 

Adding stuff into Jason's answer:

Also, that's why daily meetings, pair programming, code review are for. In these informal meetings, you say what you have done (created a temporary file) to the team, so if someone already has done it, or they also need it, you know you have to refactor into a utility library. Else you just leave the method there.

I know you mentioned you work alone, but communication is key to avoid code duplication and lots of those code smells, so this advice is mostly for teams, not standalone programmers.

Edison Gustavo Muenz
+1  A: 

Refactoring is good. While you might not want to start by reading this thesis about refactoring, it is a good read and puts it all in perspective. You might also want to check the answers to http://stackoverflow.com/questions/441896/how-to-be-master-in-c-and-object-oriented-technology which have a book on refactoring.

The bottom line is that you don't have to put all the code in the right place and organize it in the right way. Do something that is good enough for now, make note of it in a possible refactoring list, and when you have some time, go through the list and take a fresh look at the code. Maybe good enough, is good enough. If not, help the code to EVOLVE into something better.

Michael Dillon