I have a generic helper class (1) that can be used in other projects also. Imagine something like basic handling of file and folders, something useful and DRY that always come in handy.
I have another class (2) that is project specific, but it uses the generic class (1) to accomplish things.
The generic helper class (1) is used by creating a new object of it in specific places where is needed in the project.
GenericHelperClass ghc = new GenericHelperClass();
Same goes for the project specific class (2), is being used by creating a new object of it in specific places where is needed in the project.
ProjectSpecificClass psc = new ProjectSpecificClass();
But as I said the project specific class (2) uses the generic helper class (1) to do stuff.
So here I thought, that the project specific class (2) should have its own private generic helper class (1) to do its job.
But wait, there is going to be an instance of that generic helper class (1) in the project already, so why creating another one? Let's just pass that instance of (1) on the constructor of (2).
So (2) is now created like:
GenericHelperClass ghc = new GenericHelperClass();
// code and code and code
// .
// .
ProjectSpecificClass psc = new ProjectSpecificClass(ghc);
with this I have only one object of GenericHelpClass, and I have avoided using static.
The question is: Am I wrong here or am I just creating spaghetti-dependencies or something? Any suggestions?
(the names selection GenericHelperClass/ProjectSpecificClass is just for demonstration)
2 Answers 2
There are some reasons which can make this design the better alternative:
GenericHelperClass ghc = new GenericHelperClass();
// ...
// using `ghc` here for other purposes
//...
ProjectSpecificClass psc = new ProjectSpecificClass(ghc);
if the construction of
ghc
is slow or needs lots of resources, it might be better to construct the object only onceif after construction of
ghc
the object has to be initialized in a specific way before it can be used, it is better to do this initialization only onceyou want to expect the constructor of
ProjectSpecificClass
an object of typeIGenericHelperClass
(an interface) to make it possible to "mock the object out" for unit testing purposes
If none of the reasons apply to your case, keep things as simple as possible for the user of ProjectSpecificClass
and construct the object inside, where it is needed, even when this is done twice. Standard object construction in C# is very fast, as long as there is no "heavy-weight" constructor code in place.
-
Thank you for your answer. Creating that general helper twice (once in project and once internally in the project-specific-class) will surely make things less complex, and would lead to just forget about it. But i am willing to add a bit "complexity" should i say? by just creating the general helper one time and then make sure i am passing it to the project specific class. (Since wherever i use the project specific class there is always the general helper also already present). So i think i won't "keep things as simple as possible" for the sake of micro(?)optimization - not sure if actuallySharky– Sharky2016年02月01日 14:31:21 +00:00Commented Feb 1, 2016 at 14:31
-
..worths it. Well whatever, it starts feeling like paralysis by analysis. i should move on. Thanks again Doc!Sharky– Sharky2016年02月01日 14:31:47 +00:00Commented Feb 1, 2016 at 14:31
-
1I am pretty sure you can mock the object even without using an interface. The basic usage of dependency injections fulfills the contract.Andy– Andy2016年02月01日 15:12:33 +00:00Commented Feb 1, 2016 at 15:12
My own thought on these sorts of helpers are in effect filling in lacuna in the standard library. They should therefore be held to the same sort of rigorous standards that the standard library is held to. Particularly if this helper class(es) is being used in multiple project, it is essential to validate it with extensive testing. Just as the presumed high quality, stability and general utility of the interface of the standard library justify tighter coupling than to other interfaces which lack these qualities, directly instantiating a GenericHelperClass
on need is usually justifiable.
Of course the extent to which you should decouple from the GenericHelperClass
depends not only on its quality and stability, but also the domain(s) in which it is used. If the GenericHelperClass
forms part of the interface to external systems such as databases or web apis, it is generally worthwhile to decouple from it and program to an interface so that it may be replaced by a double for unit tests. In the other direction, if GenericHelperClass
is used to implement well known, pure functionality -- think a base64 encoder, mathematical functions or utility methods on collections -- this will be a waste of effort. Indeed, for this sort of use, it is completely acceptable to make GenericHelperClass
static. (It's for this reason that Math
is generally a static class.)
So in conclusion, it's difficult to say whether coupling SpecificHelperClass
to GenericHelperClass
is a bad or good idea without knowing the purpose of those classes. One general quasi-solution is to provide multiple constructors for SpecificHelperClass
, one that allows a double of GenericHelperClass
to be used for testing purposes and a default one that just uses GenericHelperClass
.
-
Thank you for your answer. It implements pure functionality, so it could be static, but i don't know it feels wrong. Mostly because that generic helper class is not used across the whole project, but only in some specific parts. Practically, static-ing it won't eat up significant resources, they are just a couple of functions, but theoretically its a waste having it static just idling there in memory for most of the time.Sharky– Sharky2016年02月01日 13:55:40 +00:00Commented Feb 1, 2016 at 13:55
-
1@Sharky: "its a waste having it static just idling there in memory for most of the time" sounds like premature optimization. There are other reasons why a class might be not static, but what you wrote looks to me like a wrong reason.Doc Brown– Doc Brown2016年02月01日 14:21:26 +00:00Commented Feb 1, 2016 at 14:21
-
@DocBrown im hearing you. im a bit confused and burned out atm. and maybe years of badmouthing static's made me stubborn.Sharky– Sharky2016年02月01日 14:34:54 +00:00Commented Feb 1, 2016 at 14:34
FileExists
function without repeating myself? Thanks again, im all ears waiting for your response!