{"id":4846,"date":"2014-03-30T16:05:42","date_gmt":"2014-03-30T16:05:42","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2014\/03\/30\/working-with-injectable-singletons-collection-of-common-programming-errors\/"},"modified":"2014-03-30T16:05:42","modified_gmt":"2014-03-30T16:05:42","slug":"working-with-injectable-singletons-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2014\/03\/30\/working-with-injectable-singletons-collection-of-common-programming-errors\/","title":{"rendered":"Working with Injectable Singletons-Collection of common programming errors"},"content":{"rendered":"<p>The concept described in that article is an Ambient Context that uses a Service Locator in the background.<\/p>\n<p>Because of the use of a static property and the use of the Service Locator, this pattern is very inconvenient for unit testing. To be able to run a test that verifies code that uses this singleton, you need to set up a valid Service Locator and configure it with the singleton (probably a mock instance) that you care about using testing.<\/p>\n<p>Even the example given by the article already suffers from these problems, since the &#8220;Do you like singletons?&#8221; code, is hard to test:<\/p>\n<pre><code>if (DialogDisplayer.getDefault().yesOrNo(\n    \"Do you like singletons?\"\n)) {\n    System.err.println(\"OK, thank you!\");\n} else {\n    System.err.println(\n        \"Visit http:\/\/singletons.apidesign.org to\"\n        + \" change your mind!\"\n    );\n}\n<\/code><\/pre>\n<p>A better alternative is to use constructor injection to inject that singleton (please excuse my French, but I&#8217;m not a native Java speaker):<\/p>\n<pre><code>public class AskTheUserController\n{\n    private DialogDisplayer dialogDisplayer;\n    private MessageDisplayer messageDisplayer;\n\n    public AskTheUserController(DialogDisplayer dialogDisplayer,\n        MessageDisplayer messageDisplayer)\n    {\n        this.dialogDisplayer = dialogDisplayer;\n        this.messageDisplayer = messageDisplayer;\n    }\n\n    public void AskTheUser()\n    {\n        if (this.dialogDisplayer.yesOrNo(\n            \"Do you like singletons?\"\n        )) {\n            this.messageDisplayer.display(\"OK, thank you!\");\n        } else {\n            this.messageDisplayer.display(\n                \"Visit http:\/\/singletons.apidesign.org to\"\n                + \" change your mind!\"\n            );\n        }\n    }\n}\n<\/code><\/pre>\n<p>There was another &#8216;hidden&#8217; dependency in that code: <code>System.err.println<\/code>. It got abstracted using a <code>MessageDisplayer<\/code> interface. This code has a few clear advantages:<\/p>\n<ul>\n<li>By injecting both dependencies, the consumer doesn&#8217;t even need to know that those dependencies are singletons.<\/li>\n<li>The code clearly communicates the dependencies it takes.<\/li>\n<li>The code can easily be tested using mock objects.<\/li>\n<li>The test code doesn&#8217;t need to configure a service locator.<\/li>\n<\/ul>\n<p>Your tests might look like this:<\/p>\n<pre><code>@Test\npublic void AskTheUser_WhenUserSaysYes_WeThankHim()\n{\n    \/\/ Arrange\n    bool answer = true;\n\n    MockMessageDisplayer message = new MockMessageDisplayer();\n    MockDialogDisplayer dialog = new MockDialogDisplayer(answer);\n\n    AskTheUserController controller =\n        new AskTheUserController(dialog, message);\n\n    \/\/ Act\n    controller.AskTheUser();\n\n    \/\/ Assert\n    Assert.AreEqual(\"OK, thank you!\", message.displayedMessage);\n}\n\n@Test\npublic void AskTheUser_WhenUserSaysNo_WeLetHimChangeHisMind()\n{\n    \/\/ Arrange\n    bool answer = true;\n\n    MockMessageDisplayer message = new MockMessageDisplayer();\n    MockDialogDisplayer dialog = new MockDialogDisplayer(answer);\n\n    AskTheUserController controller =\n        new AskTheUserController(dialog, message);\n\n    \/\/ Act\n    controller.AskTheUser();\n\n    \/\/ Assert\n    Assert.IsTrue(\n        message.displayedMessage.contains(\"change your mind\"));\n}\n<\/code><\/pre>\n<p>Your test code will never be as intend revealing as the code above when you&#8217;re using the &#8216;injectable singleton&#8217; pattern as shown in the article.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The concept described in that article is an Ambient Context that uses a Service Locator in the background. Because of the use of a static property and the use of the Service Locator, this pattern is very inconvenient for unit testing. To be able to run a test that verifies code that uses this singleton, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-4846","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/4846","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=4846"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/4846\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=4846"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=4846"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=4846"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}