Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Dependency Injection vs. Global/Static data

Reply
Thread Tools

Dependency Injection vs. Global/Static data

 
 
thomas
Guest
Posts: n/a
 
      09-02-2010
Hi,

----injection---
class Util{
public:
void print(){...}
};

class Work{
void SetUtil(Util* pUtil){m_pUtil = pUtil;}
Util* m_pUtil;
};
----end----

----static----
class Util{
public:
static void print(){...}
};
----------
What's the advantages/disadvantages when comparing these two methods?
When I use these two methods in dll interface(Work class inside dll;
Util may be used by several modules.), anything I need to take special
care of?
 
Reply With Quote
 
 
 
 
Vladimir Jovic
Guest
Posts: n/a
 
      09-02-2010
thomas wrote:
> Hi,
>
> ----injection---
> class Util{


this class is missing base to use it in dependency injection

> public:
> void print(){...}
> };
>
> class Work{
> void SetUtil(Util* pUtil){m_pUtil = pUtil;}
> Util* m_pUtil;
> };
> ----end----
>
> ----static----
> class Util{
> public:
> static void print(){...}
> };
> ----------
> What's the advantages/disadvantages when comparing these two methods?
> When I use these two methods in dll interface(Work class inside dll;
> Util may be used by several modules.), anything I need to take special
> care of?


The 1st method gives you flexibility, while the second is fixed. If you
provide a base class for Util class, you can easily use another
implementation later on, and switch between two
 
Reply With Quote
 
 
 
 
Alf P. Steinbach /Usenet
Guest
Posts: n/a
 
      09-02-2010
* thomas, on 02.09.2010 10:14:
>
> ----injection---
> class Util{
> public:
> void print(){...}
> };
>
> class Work{
> void SetUtil(Util* pUtil){m_pUtil = pUtil;}
> Util* m_pUtil;
> };
> ----end----
>
> ----static----
> class Util{
> public:
> static void print(){...}
> };
> ----------
> What's the advantages/disadvantages when comparing these two methods?


There is no polymorphism for either design.

In the first example you have the option of turning off and on printing. This
could much more easily be accomplished via a boolean member in 'Work' + an
internal print method that checks the boolean.

If you meant for 'print' to be virtual, then the first example offers the
additional functionality of customizing the effect of 'print'.

Presumably you know that, and whatever advantage depends on your requirements,
which you fail to state here. However, if the second example is a possible
solution for your requirements, then there is no current advantage, only a
possible future advantage. And in that case it's purely a methodology question,
"Should one design for possible future requirements?", and off-topic here.

C++ aspect: for the second example, use a namespace, not a class.


> When I use these two methods in dll interface(Work class inside dll;
> Util may be used by several modules.), anything I need to take special
> care of?


That's a Windows question, not a C++ question.


Cheers & hth.,

- Alf

--
blog at <url: http://alfps.wordpress.com>
 
Reply With Quote
 
thomas
Guest
Posts: n/a
 
      09-02-2010
I should have provided more information.
-----base class---
struct IUtil{
virtual void print(){}
};
----end-----

----injection---
class Util : public IUtil{
public:
void print(){...}
};

class Work{
void SetUtil(IUtil* pUtil){m_pUtil = pUtil;}
IUtil* m_pUtil;
};
----end----

----static----
class Util{
public:
static IUtil* s_pUtil;
};
IUtil* Util::s_pUtil = NULL; //Util::s_pUtil = pUtil; (do assignment
somewhere else.)
----------

From the above code you can see that both provides flexibility. The
only difference is the implementation methods.
So any essential difference?
 
Reply With Quote
 
Goran Pusic
Guest
Posts: n/a
 
      09-02-2010
On Sep 2, 12:05*pm, thomas <(E-Mail Removed)> wrote:
> I should have provided more information.
> -----base class---
> struct IUtil{
> * * virtual void print(){}};
>
> ----end-----
>
> ----injection---
> class Util : public IUtil{
> public:
> * * void print(){...}
>
> };
>
> class Work{
> * * void SetUtil(IUtil* pUtil){m_pUtil = pUtil;}
> * * IUtil* *m_pUtil;};
>
> ----end----
>
> ----static----
> class Util{
> public:
> * * static IUtil* s_pUtil;};
>
> IUtil* Util::s_pUtil = NULL; //Util::s_pUtil = pUtil; (do assignment
> somewhere else.)
> ----------
>
> From the above code you can see that both provides flexibility. The
> only difference is the implementation methods.
> So any essential difference?


I'll presume that Work class has e.g. this:

void Work::work() {... m_pUtil->print(); ...}

If all instances of Work should use same Util, then clearly m_pUtil is
overkill. If not, then it isn't. But we don't know any of that, so we
can't tell you. It is very hard to guess these things, and it is very
hard to predict the future.

If, for example, at this stage, you use one Util for all Work-s, but
think that you might need separate ones later, you can do e.g.:

class Work
{
....
Util* GetUtil() { return GetGlobalUtil(); }
....
};

and not use m_pUtil anymore. Then, once you realize that you do want
several Util-s, just add your SetUtil and change GetUtil to:

Util* GetUtil() { return m_pUtil; }

That way, you get simpler design, no runtime cost, and the ability to
change later with less actual code changes.

Goran.
 
Reply With Quote
 
thomas
Guest
Posts: n/a
 
      09-02-2010
Thanks. Hm.. sorry for bad expression.

I want to print debug messages and hope that I can change output
destination according to different requirements.
There're two ways: dependency injection; static/global instances.
I think "static/global instances[method II] is enough, but I wonder
whether there's anything bad to my design I don't know.

-----Monitor class---
struct IMonitor{
virtual void print(){}
};
class Monitor : public IMonitor{
public:
void print(){...}
};
----end-----

[method I]
----injection---
class Work{
void SetMonitor(IMonitor* pMonitor){m_pMonitor = pMonitor;}
IMonitor* m_pMonitor;
};
----end----
To print messages, call "m_pMonitor->print()"

[method II]
----static----
class Util{
public:
static IMonitor* s_pMonitor;
};

IMonitor* Util::s_pMonitor = NULL; //Util::s_pMonitor = pMonitor; (do
assignment
somewhere else.)
-------end-----
To print messages, call "Util::s_pMonitor->print()"
 
Reply With Quote
 
Pavel
Guest
Posts: n/a
 
      09-03-2010
thomas wrote:
> Thanks. Hm.. sorry for bad expression.
>
> I want to print debug messages and hope that I can change output
> destination according to different requirements.
> There're two ways: dependency injection; static/global instances.
> I think "static/global instances[method II] is enough, but I wonder
> whether there's anything bad to my design I don't know.
>
> -----Monitor class---
> struct IMonitor{
> virtual void print(){}
> };
> class Monitor : public IMonitor{
> public:
> void print(){...}
> };
> ----end-----
>
> [method I]
> ----injection---
> class Work{
> void SetMonitor(IMonitor* pMonitor){m_pMonitor = pMonitor;}
> IMonitor* m_pMonitor;
> };
> ----end----
> To print messages, call "m_pMonitor->print()"
>
> [method II]
> ----static----
> class Util{
> public:
> static IMonitor* s_pMonitor;
> };
>
> IMonitor* Util::s_pMonitor = NULL; //Util::s_pMonitor = pMonitor; (do
> assignment
> somewhere else.)
> -------end-----
> To print messages, call "Util::s_pMonitor->print()"

If it were not for debugging, I would say the first snippet has
advantages of flexibility, easier adoption to multi-tasking (Monostates
are notoriously difficult to deal with in multi-threaded environment,
and dynamic libraries are not helping).

The second is simpler to implement, less intrusive to the existing
classes, slightly faster at run-time, takes no memory in the object,
easier to control as an "aspect" (e.g. turn printing on or off
on-the-fly or via compilation macro).

As it is for debugging, 2nd method seems to be more appropriate. I would
not even hesitate to use a macro like UTIL_PRINT() to make sure I can
remove this code from the binary at compilation time w/o an issue.

-Pavel
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Immutable cyclic graph with dependency injection Philipp Java 8 06-29-2009 07:53 PM
Is it in the C++ culture to use Dependency Injection/Inversion ofControl? Danno C++ 12 04-10-2008 08:08 PM
What is Dependency Injection? Anonieko ASP .Net 2 10-14-2007 12:03 PM
Dependency Injection in C++ Michael Feathers C++ 5 10-13-2006 08:23 AM
How to build a dependency injection framework by myself? =?iso-8859-1?B?bW9vcJk=?= Java 4 08-24-2006 06:57 PM



Advertisments