Hmm, I think some of the motivation here is not valid, such the search field 
that has to know about the search result view.

If you put a mediator in between a search field (stimulus) and the search 
result panel 
you get a place to put UI agnostic logic if needed and at the same time keeping 
the standard 
SearchResult search(SearchCriteria) signature.


SearchPanel --> Mediator ----> SearchMethod
                                        -----> SearchResultPanel

I haven't followed much of this thread so if this seems irrelevant at this 
stage, have patience with me :=)

/Niklas 

2009-03-12 Rickard Öberg  wrote:

Hey,
>
>So, yesterday I tried reworking my StreamFlow workflow app into using 
>the hexagonal architecture. So far I am extremely happy with the 
>results. One of the things I have had big trouble with before is to 
>implement the "TellDontAsk" principle. It seemed like no matter what I 
>did I had to, in the end, ask for model information in various ways, 
>thus showing all the inner details that I had been trying to encapsulate 
>with my private mixins etc.
>
>With the hexagonal architecture, where UI can be "at the bottom", and 
>considered "output", this problem went away. Let me give you an example. 
>In the app there is a search field and a search result view. In a normal 
>layered app there would be a UI component that takes the search string 
>and sends it to the application layer, and then presents the results. 
>The app layer would have a method like this:
>SearchResult search(String query);
>
>This is very problematic though: first of all the search field has to 
>know about the search result view, so they are coupled. If I then also 
>want to update some other part in the UI the search field has to know 
>about this too. Also, it is highly likely that once I get the result, I 
>have to query the application for other things in order to present the 
>result.
>
>With hexagonal architecture this mess goes away. Since the flow is only 
>"in->out" rather than "up-down-up", the application layer method becomes:
>void search(String query);
>The application layer performs the query. When it is done it then simply 
>looks up all services that implement SearchObserver, iterates over them, 
>and pass the result to them. This can be easily done with a SideEffect 
>of the search method, and gives a good example of when to use 
>SideEffects. The code is something like this in the SideEffect:
>@Service Iterable observers;
>@This Searcher searcher.
>public void search(String query)
>{
>    for(SearchObserver observer: observers)
>    {
>       observer.refresh(searcher.searchResult().get());
>    }
>}
>---
>Since the app layer uses() the UI layer, one of the observers just 
>happens to be the search result view, which presents the results. If 
>there had been a status bar it could have also consumed the results and 
>showed a message like "Found 14 matches". Or more like, a SearchStatus 
>service would have Observed the search results, which would have 
>produced the string, which is then in turn sent to StatusObservers, one 
>of which happens to be the status bar.
>
>If the search takes a long time, the UI would be in trouble with the 
>first method, as it would essentially freeze when calling search. With 
>hexagonal architecture the search(string) method can accept the string, 
>return immediately, and then spawn off an asynchronous search that only 
>when completed notifies the observers. The time between search and 
>result can be quite long, but the UI will still be responsive in 
>between, without the UI having to do the thread trickery. When consuming 
>the results the UI does, however, have to ensure that it is on the Swing 
>thread.
>
>In any case, a key point is that the search field *does not have to 
>know* how to present the results. All it does is take the string and 
>send it to the application for querying. What happens then is up to the 
>application and observers of the model that the processing changes. 
>Input and output are separated in code, but still both are presented on 
>the UI screen.
>
>In this way there *is only TELL*, no ask. All events come from the 
>outside, goes to the inside (through app->domain), and then goes out
>again. And sometimes the initiator (UI) just happens to be the output too.
>
>This would also simplify testing, as the call to the app and 
>introspection of the resulting model using a mock observer is quite easy 
>to do.
>
>NEAT!
>
>/Rickard
>
>
>_______________________________________________
>qi4j-dev mailing list
>[email protected]
>http://lists.ops4j.org/mailman/listinfo/qi4j-dev
>
>
_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev

Reply via email to