开发者

Object Oriented Programming principles

I was wondering, I recently read an article that spoke of the ills of using the singleton pattern siting the disadvantage of global variable occurrence and rightly that the singleton violates alot of the rules we learn from OOP school, single responsibility principle, programming to interfaces and abstract classes and not to concrete classes... all that good stuff. I was wondering how then do you work with like database connection class where you want just one connection to your DB and one object of your DB floating around. The author spoke of Dependency Injection pr开发者_如何转开发inciple which to my mind stands well with the Dependency Inversion rule. How do I know and control what object gets passed around as a dependency other than the fact that I created the class and expect everyone using it play nice and make sure they are using the right resource?!


Edit: This answer assumes you are using a dependency injection container, either one you wrote yourself, or one you got from a library. If not, then use a DI container :)

How do I know and control what object gets passed around as a dependency other than the fact that I created the class and expect everyone using it play nice and make sure they are using the right resource?!

By contract

The oral contract - You write a design spec that says "thou shalt not instantiate this class directly" and "thou shalt not pass around any object you got from the dependency injection container. Pass the container if you have to".

The compiler contract - You give them a dependency injection container, and they grab the instance out of it, by abstract interface. If you want only a single instance to be used, you can supply them a named instance, which they extract with both the name, and the interface.

ISomething instance = serviceLocator.ResolveInstance<ISomething>(
  "TheInstanceImSupposedToUse");

You can also make all your concrete classes private/internal/what-have-you, and only provide them an abstract interface to operate against. This will prevent them from instantiating the classes themselves.

// This can only be instantiated by you, but can be used by them via ISomething
private class ConcreteSomething : ISomething
{
    // ...
}

By code review

You make group-wide coding and design standards that are fair, and make sure they are understood by everyone within the group.

You use a source control mechanism, and require code reviews before they check in. You read over their code for what they link to, what headers they include, what objects they instantiate, and what instances they are passing around.

If they violate your rules during code reviews, you don't let them check in until they fix their code. Optionally, for repeat offenders, you make them pay you a dollar, you make them buy you lunch, or you hire a different contractor to replace them. Whatever works well within your group :)


For those who criticize the singleton pattern, based on SRP, here is an opposing view. Also, I've found that dependency injection containers can create as many problems as they solve. That said, I'm using a promising compromise, as covered in another post.


Dependency injection containers (even one you develop yourself, which isn't an entirely uncommon practice) are generally very configurable. What you'd do in that scenario is configure it such that any request for the interface that implementation, well, implements would be satisfied with that implementation. Even if it's a singleton.

For example, take a look at the Logger singleton being used here: http://www.pnpguidance.net/News/StructureMapTutorialDependencyInjectionIoCNET.aspx


Don't take what you read anywhere as absolute truth. Read it, understand it and then you can see when it's best to apply certain things. In your case, why wouldn't you want to create a static singleton?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜