Getting lost in the OOP joungle when trying to put a method in the right place etc
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 MyUtils
.
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 t开发者_如何学JAVAhan 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.
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).
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 https://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.
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.
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.
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.
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".
精彩评论