tag:blogger.com,1999:blog-5320555029216218032.comments2014-07-20T03:39:21.136-07:00Software development, both biased and fair waysAnonymoushttp://www.blogger.com/profile/08968963615797084668noreply@blogger.comBlogger10125tag:blogger.com,1999:blog-5320555029216218032.post-12067353678523678062013-02-25T09:07:02.695-08:002013-02-25T09:07:02.695-08:00Ten komentarz został usunięty przez autora.angelshttps://www.blogger.com/profile/01300706220788537399noreply@blogger.comtag:blogger.com,1999:blog-5320555029216218032.post-72615834454970892662013-01-29T12:02:42.708-08:002013-01-29T12:02:42.708-08:00You saved me from the Cake monster ;-) Thanks a lo...You saved me from the Cake monster ;-) Thanks a lot for the sober explanation.qertoiphttps://www.blogger.com/profile/04229039306559794118noreply@blogger.comtag:blogger.com,1999:blog-5320555029216218032.post-45376020239374956652013-01-15T10:58:08.071-08:002013-01-15T10:58:08.071-08:00Ten komentarz został usunięty przez autora.angelshttps://www.blogger.com/profile/01300706220788537399noreply@blogger.comtag:blogger.com,1999:blog-5320555029216218032.post-84046628171037007012011-03-30T09:38:35.758-07:002011-03-30T09:38:35.758-07:00So I guess we agree on most points :) The confusio...So I guess we agree on most points :) The confusion mainly came from the fact of me wrongly understanding the overloaded factory etc terms ;)<br /><br />Anyway, interesting post and discussion, thanks! And see you at java4people.<br /><br />AdamAdam Warskihttps://www.blogger.com/profile/04535036247623614805noreply@blogger.comtag:blogger.com,1999:blog-5320555029216218032.post-7768160747905416912011-03-24T15:00:53.954-07:002011-03-24T15:00:53.954-07:00@adamwtw
Agreed, I should have written "If yo...@adamwtw<br />Agreed, I should have written "If you'd use DI..." instead of "If you use DI...". I just wanted to stress the important distinction between the core benefit of DI against its minor, although nice additions.<br />Containers indeed can save your typing and time, though it happens, that opposite is true - it depends on how you use them (this probably deserves some other blog post).<br /><br />POFs make testing easier because you can extend a factory, selectively overriding chosen definitions, like in:<br /><br />class AppFactory {<br />/* ... */<br /> def buyer = new BuyerAgent(crawler)<br /> def crawler = new WebCrawler()<br />/* ... */<br />}<br />class CustomFactory extends AppFactory {<br /> override def crawler = new MockCrawler()<br />}<br /><br />You can do that very quickly each time you need a custom configuration while having full compiler and IDE support for potential changes in future.<br />Try to get such flexibility with popular Spring XML approach, even with context splitting, includes and classpath tricks. I deliberately don't mention Guice and Spring's recent features, because they (finally) make it good enough. Unfortunately, the old XML way is still much too common.<br /><br />With the "real polymorphism" term I wanted to express an idea, that certain combination of Spring's features gives you some kind of "emulated polymorphism". For instance it's when you split a large applicationContext.xml into 2 pieces, and then provide a modified version of one of them on the test classpath.<br /><br />Of course you don't need self-types to do DI. And I agree, that without self-types that's no longer the Cake pattern. Similarly, it's no longer Cake should you omit the namespaces thing. That's not the point, let's leave Cake what is it.<br />What is more troubling for me, people tend to use it for DI without reflecting on forces engaged, making suboptimal choices when simpler alternatives fit better.<br />Maybe that's because the pattern is lacking a description in a framework that accompanies the popular GoF patterns for example? My blog post tries to accomodate for that a bit.<br /><br />Speaking of namespaces, thanks to our conversation I've realized, that I was too quick to dismiss your point about saving keystrokes for constructor stuff. Of course there's much less typing when you nest a class inside a trait and use the declared dependencies inside. That makes the third benefit of nesting types in Cake and I should probably update my post to reflect that. <br />Keeping that in mind, there's still no excuse to nest types when it doesn't make sense. For example, nesting a top level, independent trait inside another trait just to follow the pattern's overall scheme completely misses the point.<br /><br />You've correctly noticed, that auto-wiring and compile/run-time aspects are orthogonal. Worth remembering.Anonymoushttps://www.blogger.com/profile/08968963615797084668noreply@blogger.comtag:blogger.com,1999:blog-5320555029216218032.post-72608717746955752762011-03-17T12:48:54.808-07:002011-03-17T12:48:54.808-07:00Hmm somehow I'm not getting e-mail notificatio...Hmm somehow I'm not getting e-mail notifications for new comments...<br /><br />Anyway, I never wrote that I'm only using DI to use DI containers - just that the containers are a very nice addition, esp in bigger projects. They simply spare typing, and I'm no different from an average programmer - lazy :).<br /><br />Can you give an example where testing when using a DI container over a POF is harder? I can't imagine how it differs in code, probably because I don't understand exactly what you mean.<br /><br />About the Cake - that you don't need the namespacing - agreed (I never wrote I didn't agree ;) ). In fact you don't need self-types also (but then it's not Cake) - some form of interfaces/types and parametrized construction is enough. As I wrote, DI is simply using abstraction and kind of an approach to programming.<br /><br />Also, I think that auto-wiring and run-time/compile-time impl choice are orthogonal.<br /><br />And btw. what's "real polymorphism"?<br /><br />AdamAdam Warskihttps://www.blogger.com/profile/04535036247623614805noreply@blogger.comtag:blogger.com,1999:blog-5320555029216218032.post-21695087562509062492011-03-01T05:59:21.407-08:002011-03-01T05:59:21.407-08:00@adamwtw
If you use DI only to be able to use DI c...@adamwtw<br />If you use DI only to be able to use DI containers, you miss its biggest benefit. The key value of DI is separating object-wiring logic from application logic, so you can test them independently. DI gives you that, no matter whether you use containers or not.<br /><br />Used wisely, containers can get you a lot of good, as they are powerful tools. It's a double-edged sword, though. They can easily cause more problems than they solve, especially when you strive for runtime flexibility (most often not needed - hence the current trend to use annotations and static code instead of XML).<br />It's also quite common, that a DI framework actually makes testing of an application harder than with POFs (Plain Old Factories), where you have the full spectrum of language features (including real polymorphism) at your command. In addition to that, you need no special IDE plugins to handle POFs with ease.<br /><br />So in some settings DI containers are not the best available option.<br />Cake pattern (or strictly speaking, self-types) is most useful in those settings. Trying to compare it with DI containers misses the point.<br />So I agree with your note on run-time configuration options - it's not what Cake is for. I'd say more - even the auto-wiring you mention is not that "auto" it may appear to you. Note, that you have to choose your dependencies at compile-time, by mixing them in via "with" keyword. All run-time flexibility is gone - disaster!<br /><br />In fact, you still can get all the run-time flexibility you might need, but as with other features of DI containers, you're on your own - Cake will not force any specific choice on you. Nor will it help you to achieve that - it just will not get into your way.<br /><br />The main point of my post however is not about comparing Cake with DI containers. I have pointed out, that Cake is actually a composite pattern, and if you want DI only, you don't need the whole funny (and/or confusing) namespaces stuff. From the whole Cake, only self-types are required for DI. People often don't see that, which leads them to write unnecessary, confusing code. This unfortunately applies even to people I highly regard for awesome blogs.<br /><br />To asess, whether manual DI or container-supported DI is better for you, see the relevant post on the <a href="http://misko.hevery.com/2009/01/14/when-to-use-dependency-injection/" rel="nofollow">blog of Miško Hevery</a>.<br /><br />When POFs are better in your context, Scala makes them significantly easier to maintain thanks to its shorter syntax (no need to write stupid this.a=a; this.b=b; this.c=c constructor stuff for example), support for lazy vals and self-types among others.Anonymoushttps://www.blogger.com/profile/08968963615797084668noreply@blogger.comtag:blogger.com,1999:blog-5320555029216218032.post-50008307432846840332011-03-01T03:01:15.784-08:002011-03-01T03:01:15.784-08:00Hmm well DI is really:
1. using abstraction in the...Hmm well DI is really:<br />1. using abstraction in the form of constructor parameters/setters/etc<br />2. (more psychological) remembering no to use "new" too much<br /><br />What is really nice about DI are the containers, which give you features like scoping, auto wiring, AOP, interceptors, etc.<br /><br />For me the *Components+self types in cake are just a mean to get auto wiring. And a pretty constrained one, as run-time configuration options are nearly 0.<br /><br />So changing the classes to use constructors would really be a pain to maintain once the number of components gets larger.<br /><br />AdamAdam Warskihttps://www.blogger.com/profile/04535036247623614805noreply@blogger.comtag:blogger.com,1999:blog-5320555029216218032.post-61119209029501936452011-02-24T14:52:36.502-08:002011-02-24T14:52:36.502-08:00@adamwtw Thanks for your feedback, I hope my sampl...@adamwtw Thanks for your feedback, I hope my samples will help to see my point.<br />Is the question about DI definition really that good? I'm using the obvious definitions from http://en.wikipedia.org/wiki/Dependency_injection and http://martinfowler.com/articles/injection.html here.<br /><br />In what sense is the namespacing from your example (http://www.warski.org/blog/?p=291) "proper"? It's fairly arbitrary too me. You could easily change all of your inner types into external with only a minor adjustment - members obtained via self-type should become declared as constructor parameters of the external types - for example:<br /><br />class UserAuthorizationImpl(userRepository: UserRepository) { <br /> /* previously, constructor<br /> was parameterless */<br />}<br /><br />Then you got no namespacing at all, while still having all access you need (and no others unnecessary members).<br />The namespacing in Cake serves completely different purposes - I've mentioned it in the post. It is unnecessary in your example, in fact it is harmful, because it obscures the code.<br /><br />Your question about instance of MyService used is unrelated to namespace concerns - you have total freedom of implementation choice regardless you use full Cake Pattern or self-types only.Anonymoushttps://www.blogger.com/profile/08968963615797084668noreply@blogger.comtag:blogger.com,1999:blog-5320555029216218032.post-64484287751691745832011-02-24T02:43:22.627-08:002011-02-24T02:43:22.627-08:00I think code samples very a lot to understand what...I think code samples very a lot to understand what you have in mind :). Especially on more complex topics.<br /><br />As for the self-types usage, I think the whole purpose of the MyServiceComponent with a nested MyService class is to achieve proper namespacing. That is, when you depend on a component, you don't want to get all of the service members, but you want to have access to the service class.<br /><br />Moreover, there's also the question about which instance of MyService would these methods refer to (if they are all pulled in). The method to obtain the instance can either create a new instance, lookup a scoped instance (in case of web apps), create an instance based on arguments etc.<br /><br />Also there's the good question "what is DI" ;).<br /><br />AdamAdam Warskihttps://www.blogger.com/profile/04535036247623614805noreply@blogger.com