Thanks for the answer Ben and Stephane. I already read A Mentoring Course on Smalltalk, Valloud, there is nothing there I could use in this case :( . I will look after for The Design Patterns Smalltalk Companion. Most of the sources provided I already know of or went in the same lines lines of what I have already found. About TDD, I am experienced with the discipline and have tested it on Pharo living system already, but I could not understand how this is related with object wiring, DI and service locator.
From ben:
"I'm not really familiar with IoC or DI patterns, so just taking your
example at face value, in Pharo I'd do...
MovieLister>>moviesDirectedBy: director allMovies := finder allMovies. ^ allMovies select: [ :movie | movie getDirector = director ]. "although typically #getDirector would be renamed #director"
MovieLister>>finder: movieFinder finder := movieFinder.
to be used like this... lister := MovieLister new finder: (ColonDelimitedMovieFinder on: 'movies1.txt'). movies := lister moviesDirectedBy: 'Tarantino'."
and Stephane: Why don't you simply pass the class and use that class in your MovieLister?
MovieLister new finderClass: MySuperCoolFinderClass
... MovieLister finder finderClass new .....
What is wrong with that.
That was what I meant when I said: "I know that in Smalltalk I can make MovieLister to receive, upon construction, a class representing MovieFinder and call it construction message.". The code I had in mind is a bit of mix from the one provided by you both: MovieLister>>moviesDirectedBy: director allMovies := finder allMovies. ^ allMovies select: [ :movie | movie getDirector = director ]. "although typically #getDirector would be renamed #director" MovieLister>>finder: aMovieFinderBuilder finder := aMovieFinderClass new. to be used like this... lister := MovieLister new finder: (ColonDelimitedMovieFinder builderOn: 'movies1.txt'). movies := lister moviesDirectedBy: 'Tarantino'." But that means I will have to wire dependencies by hand whenever I create a MovieLister and seek through code when and if those dependencies change. When there are lot's of dependencies it's is a considerable and tedious work. Let's see an image from Fowlers article: [image: Inline image 1] In this case, the service locator provides me with an instance and I configure the instance in the assembler, the scheme is alike for an IoC, and that would mean my implementation could be like this: MovieLister>>moviesDirectedBy: director allMovies := finder allMovies. ^ allMovies select: [ :movie | movie getDirector = director ]. "although typically #getDirector would be renamed #director" MovieLister>>initialize finder := ServiceLocator locate: FinderClass <--- This would bring the instance of finder class configured by the assembler to be used like this... lister := MovieLister new. movies := lister moviesDirectedBy: 'Tarantino'." and the assembler: Assember class>>configure: aMap put: (ColonDelimitedMovieFinder builderOn: 'movies1.txt') at: FinderClass My assembler and service locator could be even more elaborated, and provide a different MovieFinder in test scope, for different classes or wharever. It is a little convenience for Smalltalk, I will give that, but I was wandering if there was something alike in Pharo, by your answers I assuming there is nothing like that. If you do not want to have a reference at runtime to a Finder then you
need to use announcement and registration.
I didn't understand that, could you elaborate? On Mon, Jun 5, 2017 at 6:41 AM, Stephane Ducasse <stepharo.self@gmail.com> wrote:
Why don't you simply pass the class and use that class in your MovieLister?
MovieLister new finderClass: MySuperCoolFinderClass
... MovieLister finder finderClass new .....
What is wrong with that.
If you do not want to have a reference at runtime to a Finder then you need to use announcement and registration.
Stef
On Sun, Jun 4, 2017 at 11:17 PM, Vitor Medina Cruz <vitormcruz@gmail.com> wrote:
Hello,
I would like to know how people in Pharo ecosystem do to deal with object wiring, as described by Marting Fowler in https://martinfowler.com/articles/injection.html# FormsOfDependencyInjection:
"A common issue to deal with is how to wire together different elements: how do you fit together this web controller architecture with that database interface backing when they were built by different teams with little knowledge of each other."
He gives an example, I will leave it in java as it is simple enough to understand:
"class MovieLister...
public Movie[] moviesDirectedBy(String arg) { List allMovies = finder.findAll(); for (Iterator it = allMovies.iterator(); it.hasNext();) { Movie movie = (Movie) it.next(); if (!movie.getDirector().equals(arg)) it.remove(); } return (Movie[]) allMovies.toArray(new Movie[allMovies.size()]);
}"
The question is how to provide the finder object in a decoupled matter, a naive approach would be:
" private MovieFinder finder;
public MovieLister() { finder = new ColonDelimitedMovieFinder("movies1.txt");
}"
Which couples the MovieLister to the specific ColonDelimitedMovieFinder class.
Fowler explains how to decouple using an IoC framework or a Service Locator. In Java and .Net IoC is used most of the time. I Googled how this problem is approached in Smalltalk/Pharo, and I generally I found answers "that is easy to do in Smalltalk, so there is no need of a framework", what I miss is a description on *how* to do that:
https://stackoverflow.com/questions/243905/smalltalk-and-ioc https://stackoverflow.com/questions/2684326/is-there-a- dependency-injection-framework-for-smalltalk https://stackoverflow.com/questions/243905/smalltalk- and-ioc/347477#347477
I know that in Smalltalk I can make MovieLister to receive, upon construction, a class representing MovieFinder and call it construction message. As long an object that responds to this message is provided, I can create as many derivations I want and the MovieLister will be decoupled from the MovieFinder. That way, however, I still have to wire things by hand, and I am not sure if this is what I am supposed to do in order to solve the decouple problem.
Can you explain me how this is done in Pharo? It's is usually wiring by hand? Is there a simple construction that deals with the wiring problem that I cannot foresee?
Thanks in advance, Vitor