tag:blogger.com,1999:blog-76532878226642930542024-02-20T16:50:25.559+02:00Beyond 100 ClassesJava Tips and Tricks for Working with Large CodebasesJaanahttp://www.blogger.com/profile/09071115694773187816noreply@blogger.comBlogger10125tag:blogger.com,1999:blog-7653287822664293054.post-16035331239243336302012-06-14T10:44:00.000+03:002012-06-14T16:51:01.842+03:00Hands-on Video: Test-Driven Development - Java Application Skeleton<br />
Watch me code! I will use 30 minutes (split this into two videos) to create a simple Java Swing MVC application skeleton with TDD. The video is quite fast-paced so you'll need some prior knowledge about <a href="http://en.wikipedia.org/wiki/Test-driven_development">TDD (Test-Driven Development)</a>, <a href="http://en.wikipedia.org/wiki/Mock_object">mocks</a> and <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">MVC (Model-View-Controller)</a> to get most of it.<br />
<br />
This is my first video upload ever, so please forgive the bad quality of the recording. When I have time I'll try to find out what went wrong in conversions/upload and fix the video.<br />
<br />
I'd love to have some comments on this. Do you want to see more videos like this? If yes, what type of application would you like me to create?<b> I will create more only if people like this, so please comment.</b><br />
<br />
<br />
<table>
<tbody>
<tr>
<td>Tools & Frameworks:</td>
<td>Contents:</td>
</tr>
<tr>
<td><ul>
<li>Eclipse</li>
<li>m2eclipse (Eclipse Maven plugin)</li>
<li>eclEmma (Eclipse coverage plugin)</li>
<li>JUnit </li>
<li>Mockito</li>
</ul>
<br /></td>
<td><ul>
<li>Create a new Maven 2 project</li>
<li>Use Maven Central Repository to pick up testing frameworks</li>
<li>Create simple Controller, View and Model classes</li>
<li>Use mocks for testing </li>
<li>Test that exceptions are thrown</li>
<li>Use JUnit's assertThat (Hamcrest)</li>
<li>Test a method that launches a new thread</li>
<li>Switch execution to EventDispatchThread</li>
<li>Run test coverage with EclEmma</li>
</ul>
<br /></td>
</tr>
</tbody></table>
<br />
<div style="text-align: center;">
Vimeo does not offer HD video embedding, so go to the Vimeo to see the videos:<br />
<br />
<a href="https://vimeo.com/44035445">Hands-on TDD: Java (MVC) Application Skeleton Part I</a><br />
<br />
<br />
<a href="http://www.youtube.com/watch?v=vmtrfOckOjY&feature=g-upl">Hands-on TDD: Java (MVC) Application Skeleton Part II</a> (Youtube)<br />
OR<br />
<a href="https://vimeo.com/44036276">Hands-on TDD: Java (MVC) Application Skeleton Part II</a> (Vimeo, not HD)
<br />
<br /></div>
<br />
<center><div class="separator" style="clear: both; text-align: -webkit-auto;">
<br /></div>
</center>
<br />
If you like my videos, you may also like James Shore's <a href="http://jamesshore.com/Blog/Lets-Play/">Let's Play: TDD series</a>. I found that series while I was uploading my videos :)<br />
<br />Jaanahttp://www.blogger.com/profile/09071115694773187816noreply@blogger.com0tag:blogger.com,1999:blog-7653287822664293054.post-87535107420052587482012-06-03T09:42:00.000+03:002012-06-03T09:42:34.781+03:00Change of FocusHi there, I recently made a decision that is going to change the focus of this blog. I resigned. I have been working for the same employer for 13 years and I will surely miss my old colleagues, but this was something I wanted to do. <div>
<br /></div>
<div>
Now I am in a lucky position where I can, for a while, do the projects that I want. Bwahahahaa, I am the master of my universe!</div>
<div>
<br /></div>
<div>
As you read this, I'm building a nice little web application with <a href="http://www.vaadin.com/">Vaadin</a>, working against <a href="http://cassandra.apache.org/">Cassandra</a> DB. My main focus is to update my skills to the web and do that as fast as possible. </div>
<div>
<br /></div>
<div>
So, from now on you will no longer be hearing stories of the challenges with large code-bases. What you will get, I have no idea. And I am definitely not going to change my habits, so my updates will be as non-regular as before. </div>Jaanahttp://www.blogger.com/profile/09071115694773187816noreply@blogger.com0tag:blogger.com,1999:blog-7653287822664293054.post-27801610406634056292012-05-05T16:23:00.001+03:002012-05-05T17:29:01.180+03:00An Affair Between ObjectMother And TestDataBuilderI've read a handful of blog posts discussing whether to choose ObjectMother or TestDataBuilder for test data creation. Most of them goes like this: "<i>I've been using ObjectMother, but now I have found the TestDataBuilder and I'm ditching the ObjectMother for it</i>". Others warn you that "<i>ObjectMother is just another name for GodClass antipattern and you should never use it - use TestDataBuilder</i>". Reading those one could easily think that ObjectMothers are not good for anything.<br />
<br />
But wait a moment! If your ObjectMother gets bloated and filled with methods like createAFilthyRichCustomerWhoDrivesAPorsche() then it is not the ObjectMother to blame, but you and your fellow programmers. Any class can become a GodClass if one decides to make it such. You can always build a horrendous test data setup and hide it somewhere, too.<br />
<br />
ObjectMother should not be a dump for miscellaneous methods that give name to a multipage test data creation vomit, but a helper that offers centralized methods to create test data. Instead of createAFilthyRichCustomerWhoDrivesAPorsche() it could have methods like Customer newCustomer(String name) and addCars(Customer customer, Car... cars). Often you will find that the methods in ObjectMother are useful for the production code and you end up moving some of them there.<br />
<br />
I think it is a good approach to start with ObjectMother and introduce the TestDataBuilder when there is a need to create more complex objects or to avoid dependency injections. At start the ObjectMother could create the customer like this:<br />
<br />
<code>
public Customer newCustomer(String name){</code><br />
<code> Customer customer = new Customer(name);</code><br />
<code> customer.setFunds(1000); </code><br />
<code> return customer;</code><br />
<code>} </code><br />
<span style="font-family: monospace;"><br /></span><br />
Later on when customer gets more complicated you can easily let the ObjectMother use TestDataBuilder:<br />
<br />
<code>public Customer newCustomer(String name){<br /> Customer customer = testCustomer().name(name).build();<br /> return customer;</code><br />
<code>} </code><br />
<code><br /></code><br />
<code>public CustomerBuilder testCustomer(){</code><br />
<code>return </code><span style="font-family: monospace;">new CustomerBuilder().defaultData();</span><br />
<code>}</code><br />
<br />
Now ObjectMother works as a dictionary for existing TestDataBuilders and it has methods that ease up their use. So it really works as a helper for building test data.<br />
<br />
My TestDataBuilders don't add default data to the created test objects unless it is asked from them. We started with builders that did, but soon found out we wanted to use the empty versions too. We have data with deep hierarchies and for some test cases we just wanted an empty data with all child elements at place and empty too. So I added a separate method for adding a default data and a method verifyDefaultData() to verify that data.<br />
<br />
You also might have noticed how I said you can use TestDataBuilder to avoid dependency injections. I don't advocate dependency injections. Most often they are used to inject critical dependencies and adding public or protected methods to access them just breaks encapsulation. I rather give dependencies in constructor and raise an exception if they are missing. TestDataBuilder lets you construct the test data in phases just like dependency injection would.<br />
<br />
<code>@Test<br class="Apple-interchange-newline" />public void testCustomerIsAddedToDb(){</code><br />
<code> Db dbMock = mock(Db.class);</code><br />
<code> Register register =
mother.testRegister().db(dbMock).build();</code><br />
<span style="font-family: monospace;"> Customer john = mother.newCustomer("John");</span><br />
<span style="font-family: monospace;"> register.addCustomer(john);</span><br />
<span style="font-family: monospace;"> verifyCustomerAddedToDb(john, dbMock);</span><br />
<code>}</code><br />
<br />
What I also don't advocate is <a href="http://nat.truemesh.com/archives/000726.html">wrapping TestDataBuilders inside each other</a>. You might be tempted to do that to make code look cleaner, but please don't. There are several reasons against. Every now and then you'll want to feed the TestsDataBuilder a real item instead of a builder. You'll end up having to implement both customer(CustomerBuilder builder) and customer(Customer customer). Also, when you give your builder away you no longer see when the build is actually called. Look at this:<br />
<br />
<code>public void createAProblem(){</code><br />
<span style="font-family: monospace;"> CustomerBuilder builder = mother.testCustomer();</span><br />
<span style="font-family: monospace;"> AddressBuilder aBuilder = mother.testAddress();</span><br />
<span style="font-family: monospace;"> builder.address(aBuilder);</span><br />
<span style="font-family: monospace;"> aBuilder.street("Abbey Road");</span><br />
<span style="font-family: monospace;"> Customer customer = builder.build();</span><br />
<code>}</code><br />
<br />
Can you tell me what street the customer lives in? You'll have plenty of work dealing with real problems so keep your builders clean and simple.<br />
<br />
If you want to read more about managing test data then Jay Fields' <a href="http://blog.jayfields.com/2009/01/most-java-unit-tests-consist-of-class.html">Creating Objects in Java Unit Tests</a> is a nice read. Jay is using something he calls DomainObjectBuilder in place of the ObjectMother. I think the idea is the same though - single access point to TestDataBuilders.Jaanahttp://www.blogger.com/profile/09071115694773187816noreply@blogger.com0tag:blogger.com,1999:blog-7653287822664293054.post-34304949322264828882012-02-18T13:57:00.001+02:002012-03-24T12:19:04.620+02:00Test Driven Development Is The Heart Of Agile<br />
I am working for a large company that has selected agile as our working ideology. In practice it means that we all follow the Agile Manifesto principles, but inside the teams we are quite free to select our ways of working. While some teams absolutely love agile some teams deeply dislike it. I enjoy being agile, but I during this sprint I have learned in the hard way why some teams don't. I would like to share my experience with you.<br />
<br />
<br />
<span style="font-size: large;">Let's Try Pair Programming</span><br />
<br />
Some time ago our little Java team was merged with another scrum team that works on the same functionality area but mainly uses Bash and Perl. In this sprint all the tasks landed to the code unfamiliar to the previous Java team members. As we have good experiences on pair programming we suggested it would be a good way to get familiar to the code and get the tasks done. We were wrong.<br />
<br />
<b>The Pair Programming Just Did Not Work</b><br />
<br />
We tried pair programming with different tasks and different people. To our surprise it was not fun anymore and it was not effective. It seemed to slow down the work, confuse people, mix up responsibilities and decrease the quality. Some people felt that they did not get enough keyboard-time while others felt that they would have been faster on their own.<br />
<br />
At first I was dumbfounded, but then I paired with a colleague from my previous team. We had previous experience of pair programming together, but we were suddenly having similar problems too. What had gone into us? After a while I realized what we did differently.<br />
<br />
<b>Test Driven Development (TDD) Was Not Used</b><br />
<br />
What has TDD or any other XDD-method to do with pair programming? A lot actually. After this experience I believe that test/behavior driven methods enable pair programming. However I looked at the problems that we had, I realized that we would not have had them if we were using TDD. Here are some examples.<br />
<br />
<br />
<span style="font-size: large;">How Do I Know What He Is Thinking?</span><br />
<br />
"Doesn't that regular expression leave out the thing X that we want now?", I asked from my pair. "Oh no, I'm not parsing that thing right now. I'm parsing Y first then we do X", he replied.<br />
<br />
I could see the method names and knew what the code did when he got it ready, but I could not see my pair's intentions and reasons while he was doing it. Of course I could always stop him and ask, but then he would need to stop and cut the flow to explain me. And when I did stop him, we ended having long discussions about how the task should be implemented.<br />
<br />
<b>TDD - "Let The Red Light Guide You"</b><br />
<br />
If we had been doing TDD, we would have started by running the test cases. There would be a red one, the failed case he would be fixing. I would read the title of the case and know immediately what we wanted the new code to do. He would open the test case and I would see what aspect of the code is failing. Then he would just move to the code and start fixing it. No lengthy discussions. And if I would have been there from the start, I would have seen how he constructs the test case and that would tell me even more about his intentions.<br />
<br />
<br />
<span style="font-size: large;">Is It My Turn Already?</span><br />
<br />
I had been watching him code quite a while. I had already asked for my turn five minutes ago, but he just did not get it to stop. I could see that he had something more in his mind that he was afraid he would forget if he would not do it right away and he mumbled something along. So well... I could wait...<br />
<br />
And when it was my turn, I noticed I did the same thing - we all did. We suddenly did not want to let go of the keyboard.<br />
<br />
<b>TDD - Each Test Is a Mini Task</b><br />
<br />
That says it, doesn't it. Natural stopping places and a reminder to tell you what you were about to do.<br />
<br />
<br />
<span style="font-size: large;">What Did You Do Last Evening?</span><br />
<br />
We have different working time preferences and we have meetings that cut the day every now and then. That means we either need to pause the task or program on our own. With our schedules pausing is not a real option. So whenever either one of us jumped in, the other had to explain what s/he had done in the meantime. Whenever one of us was leaving, we had to make deals again. At the end of the task we were really confused about what got done and what did not.<br />
<br />
<b>TDD - "Let The Red Light Guide You"... again</b><br />
<br />
We were programming when my pair said he needed to go somewhere. "I'll be back in an hour", he said. "Well, I want to leave right after four today, so I won't be here when you will come back", I replied. "No problem, you can just continue here on my PC. Lock it when you leave", he said. And so we did. He came back later on that evening and picked up from where I left. Next morning I came to work early and continued where he left. That is something you just cannot do without tests that you can easily run to see what all has been done and where.<br />
<br />
It is a good practice to leave a failing case behind when you have to stop working (but cannot commit to version control yet). That way your pair (or yourself) will know where to continue.<br />
<br />
<br />
<span style="font-size: large;">How Do We Know Everything Is Done?</span><br />
<br />
Well, we are supposed to try it out, of course. But we are being agile now so there is no test plan. For some reason these tasks are not of small size either, like they used to be. We tried out the code and it seems to work, but I'm not really sure it if does all that is needed. I'm not feeling confident about this code. Maybe we just forgot to implement something.<br />
<br />
<b>TDD - Test Is The Specification</b><br />
<br />
How we used to solve this was to implement two levels of test cases to guide us.<br />
<br />
While I would be implementing the functionality our architect-tester would implement the higher level test cases for it. Higher level test cases describe the wanted behavior. Sometimes we planned the tests together in the start of the sprint and the test steps became implementation tasks that we then put to our backlog. In best sprints he worked a bit ahead and the test was ready before we started the actual programming.<br />
<br />
Did you notice how I said "Architect-Tester"? As the tests are the specification, tester and architect roles merge nicely in TDD. Esko Luontola has written a blog article about this way of thinking: <a href="http://blog.orfjackal.net/2009/10/tdd-is-not-test-first-tdd-is-specify.html">TDD is not test-first. TDD is specify-first and test-last</a><br />
<br />
The lower level test cases would be the module test cases that we did while programming. They provide us a list of mini tasks that got done.<br />
<br />
Then we could just look at the module test case list and see that everything is done, and run the higher level test cases to see that the functionality as a whole does what was wanted.<br />
<br />
<br />
<span style="font-size: large;">Why Don't We Use TDD Then?</span><br />
<br />
When we started working with Bash and Perl code we asked the rest of the team why TDD was not used already. We were told that it had been tried and found unsuitable. We were stubborn enough to try again and quickly found out we agree.<br />
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<b>What you need for TDD:</b></div>
<ol>
<li style="text-align: left;">Time to learn the method</li>
<li style="text-align: left;">Good code refactoring tool</li>
<li style="text-align: left;">A language that supports encapsulation
</li>
<li style="text-align: left;">Continuous integration that runs your tests every time code is changed</li>
<li style="text-align: left;">Testing tool/framework</li>
</ol>
<br />
What, you thought you only need the testing tools and the right attitude? That is true for your home projects where you are the only one touching the code and it does not need to be maintained for years by several different people. But for the large scale commercial projects the situation is different.<br />
<br />
First and the most important showstopper is often time. Learning to use TDD fluently takes about a year and during that time you will be slower than normally. If we had not known the method already, we could not have even tried it - the schedules are just too tight!<br />
<br />
<b>The biggest showstopper in our case was the missing code refactoring tool</b>. Refactoring in TDD is not an optional step and it is needed especially in the test part of the code. You will find that you often need to pull common parts away, combine or split methods, rename and move stuff. One of the best things in TDD is that it helps you to create code that is very easy to refactor. If you cannot refactor, you will end up with fragile and unmaintainable code base.<br />
<br />
If you are working with old code that was not done with TDD, you need to make the code testable before you can work with it using TDD. That is done by carefully refactoring parts of the code so that you are able to test just the part that you need to change. If you don't have tools that let you refactor code safely and effectively, you just cannot use TDD.<br />
<br />
TDD also makes the code highly modular and it quickly becomes unmanageable if you cannot hide the parts that are not meant for public use. I can guarantee you'll end up with "ravioli-code" if you don't have encapsulation.<br />
<br />
If you have more than one person working with the code then you need your test cases to be run automatically every time you change the code. Otherwise you'll find that someone has made changes to the code, broke the tests and now you'll have to fix them.<br />
<br />
Previously I thought test framework a must too, but most programming languages have features that enable testing them. But that must be mentioned anyway and a good testing tool makes the process more fun.<br />
<br />
<br />
<span style="font-size: large;">Conclusion</span><br />
<br />
The common understanding seems to be that agile offers us a box of tools and methods from which we can just cherry-pick the best for our purposes. Now I understand that agile tools have dependencies to each other. What tools become unusable if we don't select certain others?<br />
<br />
I think TDD is an enabler for lots of things in addition to pair programming. Are your scrum meetings a chore and feel unnecessary? Maybe your tasks don't connect to what you are actually doing?<br />
<br />
I think that there is a real risk of just playing an "agile show" if TDD is not used. You look agile outside, your builds automated and green, but what happens inside is not agile at all - it is just a show with no go. It will feel stupid and unmotivating to the people who are forced to play the show.<br />
<br />Jaanahttp://www.blogger.com/profile/09071115694773187816noreply@blogger.com0tag:blogger.com,1999:blog-7653287822664293054.post-2121015741123575612012-01-10T15:35:00.000+02:002012-01-10T15:44:19.435+02:00Observer: Part IV - Generic ObserverThis is continuation from <a href="http://beyond100classes.blogspot.com/2011/11/observer-part-iii-java.html">Observer: Part III - Java EventListenerList</a>.<br />
<br />
Sorry for the delay. I ditched the original ending for this series and did not have time to write a new one until now. I was planning to finish by presenting you generic versions of the original Java Observer/Observable and teaching how to use them. But I changed my mind, since the interesting part about generic observer is not how to use it, but how to write it. And that is the main issue today.<br />
<br />
<br />
<span class="Apple-style-span" style="font-size: large;">Warning for the beginners! </span><br />
<br />
If you have been reading through the previous parts and are here to learn how to use the observer pattern, the generic observer is not really the best way. You are better off by sticking to the stuff that you can find in the previous parts. While making the pattern implementation generic does solve some of it's problems, it does not change the fact that the <code>Observer</code> is a concrete class that you have to inherit. Also, you would need to take these classes into your own code base, to keep and take care for the rest of your application's life.<br />
<br />
Experience is about knowing when it's best to keep things simple, and when it's worth to drive for a perfect solution that is often more complex. We are dealing with a simple pattern here, why not keep the solution simple too? <br />
<br />
<br />
<span class="Apple-style-span" style="font-size: large;">You have been warned. The perverts who want The Perfect Observer Pattern may continue...</span><br />
<br />
If you really, really want to bring in some complex stuff to your code-base, there is even MORE complicated solution you can use for the observer pattern. In his blog, <a href="http://whathecode.wordpress.com/2010/11/01/java-generic-observer/">Steven Jeuris's has solved the same problem by using dynamic proxies</a>. The solution is beautiful and uses both generics and reflection. Just a type of thing your average maintenance person is going to loooove! Just don't use it in performance-critical places as doing things through reflection is quite slow.<br />
<br />
Steven also promotes <a href="http://perfectjpattern.sourceforge.net/index.html">PerfectJPattern</a> that has generic implementations for several design patterns. Each pattern is nicely explained with code examples, see <a href="http://perfectjpattern.sourceforge.net/dp-observer.html">the Observer</a>, for example. I just stumbled into that, but it might be interesting to check how it does things and if it's good, maybe run it through the legality checks to see if it's published under a licence that the company I work with would allow. Most big companies cannot just allow you to bring in new third-party libraries without legality-check. The reason is that some open-source licences make their user applications open-source too.<br />
<br />
<br />
<span class="Apple-style-span" style="font-size: large;">Prerequisites</span><br />
<br />
While the previous parts of this series have been beginner-level, this one is not. It's not that this would be much harder to understand, just that you need some background information. So if you are a beginner, I suggest that you go through this <a href="http://docs.oracle.com/javase/tutorial/java/generics/index.html">Java lesson on Generics</a> before continuing.<br />
<br />
If you are an expert in generics, you are going to have some good laughs on my behalf. <br />
<br />
If you just stumbled in without reading the previous parts, you might want to check the Java implementation of the <a href="http://download.oracle.com/javase/6/docs/api/java/util/Observer.html"><code>Observer</code></a> interface and an <a href="http://download.oracle.com/javase/6/docs/api/java/util/Observable.html"><code>Observable</code></a> class to go with the interface. Those are the classes that we are rewriting here.<br />
<br />
Are you ready? Let's start.<br />
<br />
<br />
<span class="Apple-style-span" style="font-size: large;">Defining the signature</span><br />
<br />
When you start designing generic classes, it's always best to begin by thinking about their signatures. In this case the question is - how many generic arguments do we need here?<br />
<br />
Fortunately, the answer can be found in the book <a href="http://books.google.fi/books?id=zaoK0Z2STlkC&lpg=PA137&ots=6XojhdW0DS&dq=generic%20observer%20%3CS%2CO%2CA%3E%20java&hl=fi&pg=PA137#v=onepage&q=generic%20observer%20%3CS%2CO%2CA%3E%20java&f=false">Java Generics and Collections, page 137</a>. It gives us the following signatures:<br />
<br />
<pre class="stylecode">public class Observable<S extends Observable<S, O, A>, O extends Observer<S, O, A>, A>
public interface Observer<S extends Observable<S, O, A>, O extends Observer<S, O, A>, A>
</pre>
<br />
That is nice.... huh? S stands for Subject, O for Observer and A as Argument.<br />
<br />
It does come with a warning: "<i>So you might wonder: could the declarations be simplified by dropping the type parameter S from Observable and the type parameter O from Observer? But this won't work, since you need S to be in scope in Observable so that it can be passed as a parameter to Observer, and you need O to be in scope in Observer so that it can be passed as a parameter to Observable</i>".<br />
<br />
I guess I should have read the first 137 pages also, but I was just googling around and I did not understand the warning. There was no further explanation and I did not see any obvious reason why the extended classes should be in scope. So my little caveman brain told me: "Me more smart, me does this better, more simple".<br />
<br />
What IF we try to do this with one generic argument only? That would give us the following signatures:<br />
<br />
<pre class="stylecode">public class Observable<A>
public interface Observer<S extends Observable<A>, A></pre>
<br />
Yeah, yeah, I know it won't work, but let's just play we don't know it yet.<br />
<br />
<br />
<span class="Apple-style-span" style="font-size: large;">Trying out with one generic argument</span><br />
<br />
Here is the signature for <code>Observer</code>'s update method:<br />
<br />
<pre class="stylecode">void update(S observable, A arg);</pre>
<br />
At the same time <code>Observable</code> would manage its <code>Observers</code> like this:
<br />
<br />
<pre class="stylecode">public void addObserver(final Observer<? extends Observable<A>, A> observer)</pre>
<br />
As we implement our <code>Observable</code> we will stumble into a problem in <code>notifyObservers(A arg)</code> method. We need to call the <code>update(S observable, A arg)</code> method of the <code>Observer</code>, but it does not accept our <code>Observable</code> as an argument. Why not, the definition for S was <code><S extends Observable<A>></code>? Typing is very strict in generics and the <code>Observer</code> wants something that <b>extends</b> the <code>Observable</code>. <code>Observable</code> extends <code>Object</code>, so based on the generics rules it is not valid argument for update method. I have not yet found syntax in generics for saying: <code>"<? extends Something, but Something will do too>"</code>, and that problem actually does not go away by adding more generic arguments. So I just ended up using plain, non-typed <code>Observer</code> in <code>notifyObservers(A arg)</code> method in order to be able to pass <code>Observable.this</code> as an argument.<br />
<br />
But this little incident draws our attention to typing. Our <code>Observer</code> accepts items that are of type <code><? extends Observable<A>></code>. So is it possible that we end up passing incompatible argument to update method? Actually, in this one generic argument solution, it is. Take a look at this:<br />
<br />
<pre class="stylecode"> public class Koala extends Observable<Boolean> {
public void setHungry(final boolean isHungry) {
setChanged();
notifyObservers(isHungry);
}
@Override
public String toString() {
return "koala";
}
}
public class Tiger extends Observable<Boolean> {
public void setAngry(final boolean isAngry) {
setChanged();
notifyObservers(isAngry);
}
@Override
public String toString() {
return "tiger";
}
}
public interface KoalaObserver extends Observer<Koala, Boolean> {
}
</pre>
<br />
And here is our test case that shows the problem:<br />
<br />
<pre class="stylecode"> public void testMixedObservers() {
final Tiger tiger = new Tiger();
final KoalaObserver koalaObserver = new ZooKeeper();
tiger.addObserver(koalaObserver);
try {
tiger.setAngry(true);
}
catch (final ClassCastException ex) {
assertEquals(
"org.beyondhc.lessons.observer.genericwithonearg.GenericObserverTest$Tiger"
+ " cannot be cast to "
+ "org.beyondhc.lessons.observer.genericwithonearg.GenericObserverTest$Koala",
ex.getLocalizedMessage());
}
}
</pre>
<br />
As you can see, we can add <code>KoalaObserver</code> to <code>Tiger</code>. <code>Tiger</code> will happily accept any <code>Observer</code> that extends <code>Observable<Boolean></code>. As we cannot check for the correct type, we get an ugly <code>ClassCastException</code>. This is definitely to the worse from the original solution. It is clear now what the warning in the book meant - unless the <code>Observer</code> knows the <code>Observable</code> and vice versa, we cannot be sure that the user does not make similar mistakes than with the non-typed variants. Although I was not able to repeat this particular problem with a version that uses two generic arguments, I am pretty sure someone smarter than me can get it broken too. Thus, let's forget trying this with less arguments and return to the three-argument version.<br />
<br />
<br />
<span style="font-size: large;">Observable and Observer with 3 generic arguments</span><br />
<br />
When the signatures are set, the rest of the implementation is not that hard. But the signature does look complex, so you might be wondering about the usage. And doesn't it make this thingy really non-flexible if <code>Observable</code> is so tightly coupled with its <code>Observer</code>?<br />
<br />
It turns out that this tight coupling actually forces you to better design. First, it makes it more tempting to implement a separate interface for the <code>Observer:</code><br />
<br />
<pre class="stylecode">public interface TigerObserver extends
Observer<Tiger, TigerObserver, Boolean> {
}
</pre>
<br />
And secondly, as the <code>Observer</code> can implement only one interface, you are forced to composition if you want to observe more than one type of items:<br />
<br />
<pre class="stylecode"> public class ImprovedZooKeeper {
private final TigerObserver tigerObserver;
public ImprovedZooKeeper() {
this.tigerObserver = new TigerObserver() {
@Override
public void update(final Tiger observable, final Boolean arg) {
// Do your actions here
}
};
}
public void observerTiger(final Tiger tiger) {
tiger.addObserver(tigerObserver);
}
}
</pre>
<br />
And the composition effectively hides the <code>update</code> method so that only <code>Tiger</code> may call it.<br />
<br />
The <code>Observer</code> and <code>Observable</code> discussed in this article can be found in the <a href="http://code.google.com/p/beyondhc/source/browse/#svn%2Ftrunk%2Fbeyondhc%2Fsrc%2Fmain%2Fjava%2Forg%2Fbeyondhc%2Futil">BeyondHc util package</a>.<br />
<br />
The broken ones with 1 and 2 generic arguments are available too. They can be found on the test side of the BeyondHc, in packages<br />
<a href="http://code.google.com/p/beyondhc/source/browse/#svn%2Ftrunk%2Fbeyondhc%2Fsrc%2Ftest%2Fjava%2Forg%2Fbeyondhc%2Flessons%2Fobserver%2Fgenericwithonearg">observer.genericwithonearg</a><br />
and<br />
<a href="http://code.google.com/p/beyondhc/source/browse/#svn%2Ftrunk%2Fbeyondhc%2Fsrc%2Ftest%2Fjava%2Forg%2Fbeyondhc%2Flessons%2Fobserver%2Fgenericwithtwoargs">observer.genericwithtwoargs</a>.<br />
<br />
<br />
<br />
<br />
<br />Jaanahttp://www.blogger.com/profile/09071115694773187816noreply@blogger.com0tag:blogger.com,1999:blog-7653287822664293054.post-60126516148629409882011-11-06T10:02:00.000+02:002011-11-06T11:10:29.162+02:00Observer: Part III - Java EventListenerListThis is continuation from <a href="http://beyond100classes.blogspot.com/2011/10/observer-part-ii-degenerated-observer.html">Observer: Part II - Degenerated Observer</a>.<br />
<br />
In the previous parts, I have shown you how you may break your code by using Observer Pattern implementation that comes along in Java. I have also shown you how you can use a degenerated form of Observer Pattern.<br />
<br />
Today I am going to show you yet another way to implement this pattern. I hope you are not getting tired of koalas, since we are about to implement our Koala Zoo example again. This time we are about to use <code>javax.swing.event.EventListenerList</code>.<br />
<br />
<br />
<span style="font-size: large;">Do it better - Use <code>EventListenerList</code></span><br />
<br />
Even though <code>EventListenerList</code> is located in <code>javax.swing.event</code> package, it is in no way restricted to user interface usage. Unlike the Java <code>Observable/Observer</code>, using the <code>EventListenerList</code> does not lead to fragile code either. You can find the <code>EventListenerList</code> usage instructions in <a href="http://download.oracle.com/javase/6/docs/api/javax/swing/event/EventListenerList.html">the header of it's API documentation</a>. It's almost as old as the <code>Observable/Observer</code>, but still useful today. So go ahead and use it!<br />
<br />
Let's implement our Koala again:<br />
<pre class="stylecode"> public class Koala {
private final EventListenerList observers = new EventListenerList();
public void addKoalaListener(final KoalaObserver observer) {
observers.add(KoalaObserver.class, observer);
}
public void removeKoalaListener(final KoalaObserver observer) {
observers.remove(KoalaObserver.class, observer);
}
public void setHungry(final boolean isHungry) {
final KoalaEvent event = new KoalaEvent(isHungry);
fireKoalaChanged(event);
}
private void fireKoalaChanged(final KoalaEvent event) {
// Guaranteed to return a non-null array
final Object[] listeners = observers.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == KoalaObserver.class) {
((KoalaObserver) listeners[i + 1]).koalaUpdate(this, event);
}
}
}
@Override
public String toString() {
return "koala";
}
}</pre>
<br />
Now the <code>Koala</code> keeps it's observers stored in the <code>EventListenerList</code>. Whenever changes happen, it notifies the observers.<br />
<br />
<b>But what is up with the funny backwards loop that skips every other element? </b><br />
<br />
Well, that is taken directly from the usage instructions in the API. The <code>getListenerList</code> returns an array that contains ListenerType-Listener pairs. So the first element in the list will be the type of the listener, e.g. <code>KoalaObserver.class</code>, and the second element will be the actual listener.<br />
<br />
There only reason that I know for backwards looping is that this thingy was originally written for the Swing Events. The event handling has some rules and one of them is that the last registered listener should be notified first. That way the newly added listeners have possibility to consume events, too. Thus, the list must be processed from the back to the start. <br />
<br />
There are some suggestions about other reasons in this StackOverflow thread: <a href="http://stackoverflow.com/questions/1559488/why-is-eventlistenerlist-traversed-backwards-in-firefooxxx">Why is EventListenerList traversed backwards in fireFooXXX()</a>, but I am not buying most of those. The listener array is not going to break or anything if you loop it forwards.<br />
<br />
But let's get back to Koala Zoo.<br />
<br />
The <code>KoalaObserver</code> now uses a new <code>KoalaEvent</code>, but otherwise is has stayed the same:<br />
<pre class="stylecode"> public interface KoalaObserver extends EventListener {
void koalaUpdate(Koala koala, KoalaEvent change);
}</pre>
<br />
I kept the <code>KoalaObserver</code> interface name the same as in previous implementation, so you can compare these easily. But normally I would have called it the <code>KoalaListener</code>.<br />
<br />
The <code>KoalaEvent</code> looks like this:<br />
<pre class="stylecode"> public class KoalaEvent {
private final boolean hungry;
public KoalaEvent(final boolean isHungry) {
this.hungry = isHungry;
}
public boolean isHungry() {
return hungry;
}
}</pre>
<br />
Note how the <code>KoalaEvent</code> <code>hungry</code> field is defined final. It should be up to the <code>Koala</code> to decide whether it is hungry or not, so we do not want anyone to change that field value later. Always, if possible, try to make your classes immutable. For non-english-speakers, immutable means not modifiable, something that you cannot change after it has been created.<br />
<br />
I added the <code>KoalaEvent</code> just to demonstrate how you can deliver complex change information. Using event class is not mandatory. We could have just passed a boolean parameter in the <code>koalaUpdate</code> method.<br />
<br />
Here is our <code>ZooKeeper</code>:<br />
<pre class="stylecode"> public class ZooKeeper implements KoalaObserver {
@Override
public void koalaUpdate(final Koala koala, final KoalaEvent change) {
if (change.isHungry()) {
LOGGER.info("Oh, the " + koala
+ " is hungry. It needs some eucalyptus.");
}
}
}</pre>
<br />
While handling the events, keep in mind that you do not know who else is going to get them after you are done. So never make any changes to the events that you handle. Exception to this rule is "consuming" the events, like key presses, so that the listeners that come next know that application has already acted based on user input. Most of the events should be immutable, so you can not change them even if you wanted.<br />
<br />
And here we test that the notification is sent:<br />
<pre class="stylecode"> public void testKoalaGetsFood() {
final LogMsgCaptor logMsgCaptor = new LogMsgCaptor(LOGGER);
final Koala koala = new Koala();
final ZooKeeper zooKeeper = new ZooKeeper();
koala.addKoalaListener(zooKeeper);
koala.setHungry(true);
assertEquals("The zookeeper should get notification",
"Oh, the koala is hungry. It needs some eucalyptus.",
logMsgCaptor.getMsg());
}</pre>
<a href="http://code.google.com/p/beyondhc/source/browse/trunk/beyondhc/src/test/java/org/beoyndhc/test/LogMsgCaptor.java"><code>LogMsgCaptor</code></a> is a <a href="http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html">Mockito</a>-based helper class that I wrote to collect logged messages so that I can test what was logged. <code>Assert.assertEquals</code> comes from JUnit and it makes our test case fail if the message logged does not match to what we expected.<br />
<br />
<br />
<span style="font-size: large;">What is the difference between Java <code>Observable/Observer</code> and <span style="font-family: monospace;">EventListenerList</span>?</span><br />
<br />
Functionally, they have only minor differences.<br />
<br />
The <code>EventListenerList</code> is designed to hold several different types of listener in it. If you would be implementing an user interface class, you could stuff all your <code>MouseListeners, KeyListeners, ActionListeners</code> and what have you, to this same <code>EventListenerList</code>. When the notification time comes, you can easily define which listeners should receive which event. While <code>Observable</code> happily stores any type of <code>Observers</code>, it always notifies all of them using the same argument. <br />
<br />
But <code>Observable</code> has an inbuilt change-detection system, and that is something <code>EvenListenerList</code> does not have. The <code>Observable</code> sends notifications only if it has changed, and after the notifications have been sent, it does not send more notifications unless it is marked changed again.<br />
<br />
Stylewise, <code>EventListenerList</code> is more elegant of the two. You should always favor composition over inheritance.<br />
<br />
When you use composition, like we did here, you can hide the parts of the functionality that are not needed at the moment. If we wanted, we could easily remove the <code>removeKoalaListener</code> method from our <code>Koala</code>. But when you extend the <code>Observable</code>, you cannot hide or remove anything.<br />
<br />
You can also restrict the visibility of the methods that should not be accessed from outside the class. Take a look at the <code>fireKoalaChanged</code> method of our <code>Koala</code>. It is private, so no-one can force the <code>Koala</code> to send notifications from outside. The respective methods in the <code>Observable</code> are all public or protected. <br />
<br />
Also, as the <code>EventListenerList</code> does not come with predefined notification interface, you probably end up defining interfaces that suit your purposes better.<br />
<br />
If you really need to implement a full-fledged Observer Pattern, <code>EventListenerList</code> is an good way to do that.<br />
<br />
In the next part we are going to revisit the Java <code>Observer/Observable</code> using Generics.Jaanahttp://www.blogger.com/profile/09071115694773187816noreply@blogger.com0tag:blogger.com,1999:blog-7653287822664293054.post-38527413034761400442011-10-30T08:56:00.001+02:002011-10-30T09:08:49.791+02:00Observer: Part II - Degenerated Observer<br />
This is continuation from <a href="http://beyond100classes.blogspot.com/2011/10/observer-part-i-how-to-mess-up-your.html">Observer: Part I - How to mess up your code with it</a>.<br />
<br />
In the previous part, I demonstrated some problems caused by a poor implementation of the Observer Pattern. In this and the next parts I am going to use the same Koala Zoo example to demonstrate how to implement it better.<br />
<br />
Today we will be lazy and try to avoid implementing the pattern altogether.<br />
<br />
<br />
<span class="Apple-style-span" style="font-size: large;">Do it better - Degenerate the pattern</span><br />
<br />
Often what we see is not a need for the full-fledged Observer Pattern, but a possible future need for it. In those cases, just save yourself some time and trouble and do not implement the pattern yet. Prepare for the need, but leave the implementation for the future.<br />
<br />
Let's see how the <code>Koala</code> would be implemented using that mindset:<br />
<pre class="stylecode"> public class Koala {
private KoalaObserver keeper;
public void setHungry(final boolean isHungry) {
if (keeper != null) {
keeper.koalaUpdate(this, isHungry);
}
}
public void setObserver(final KoalaObserver keeper) {
this.keeper = keeper;
}
@Override
public String toString() {
return "koala";
}
}
</pre>
<br />
Instead of inheriting from the<code> java.util.Observable</code>, we now implement a very degenerated version of Observable ourselves.<br />
<br />
As we need only one Observer we implement method <code>setObserver</code>, instead of <code>addObserver</code>. We do not provide method for deleting the Observer, unless we really need that. There is no change detection either. Just implement the bare minimum.<br />
<br />
But we do need the interface for the <code>KoalaObserver:</code><br />
<pre class="stylecode"> public interface KoalaObserver {
void koalaUpdate(Koala koala, boolean isHungry);
}
</pre>
<br />
Note that we are now able to pass on the information with correct types. Instead of two <code>Object</code>s, we are passing the <code>Koala</code> and a <code>boolean</code> telling whether the <code>Koala</code> is hungry. If you would need to pass more information, a good rule of thumb is to have maximum of four parameters in a method. So you might add two more parameters, like <code>isAngry</code> and <code>isSick</code>, but after that you should really refactor your code and implement a <code>KoalaChangeEvent</code> that would contain the parameters that need to be passed.<br />
<br />
Now we are ready to implement the actual Observer:<br />
<pre class="stylecode"> public class ZooKeeper implements KoalaObserver, WaterPipeObserver {
@Override
public void koalaUpdate(final Koala koala, final boolean isHungry) {
if (isHungry) {
LOGGER.info("Oh, the "
+ koala
+ " is hungry. I'll go into the cage and give"
+ " some eucalyptus to the little fella!");
}
}
@Override
public void pipeFixingNeeded() {
LOGGER.info("Gonna fix the pipe now!");
}
}
</pre>
Now the class declaration nicely tells us what entities the <code>ZooKeeper</code> is observing. I added the <code>WaterPipe</code> from the previous posting to demonstrate how all the different updates no longer go to a common <code>update</code> method. We are free to invent method names that really describe what is happening. <br />
<br />
Last, here is how you would use the classes:<br />
<pre class="stylecode"> public void testKoalaGetsFood() {
final LogMsgCaptor logMsgCaptor = new LogMsgCaptor(LOGGER);
final Koala koala = new Koala();
final ZooKeeper zooKeeper = new ZooKeeper();
koala.setObserver(zooKeeper);
koala.setHungry(true);
assertEquals(
"The koala should get food",
"Oh, the koala is hungry. I'll go into the cage and give"
+ "some eucalyptus to the little fella!",
logMsgCaptor.getMsg());
}</pre>
<br />
If you now tried to do similar mistakes that we did in part I you would get compilation errors.<br />
As you can see, methods are more descriptive and it is easier to see what each of the classes do just by looking at the classes themselves.<br />
<br />
Overall, this degenerated pattern offers several advantages compared to using <code>java.util.Observable</code> and <code>java.util.Observer</code>. We have less functionality to maintain. Code is easier to read and debug. We get compilation errors if we break the pattern.<br />
<br />
<br />
<span class="Apple-style-span" style="font-size: large;">Pitfalls</span><br />
<br />
There are two pitfalls here.<br />
<br />
<b>1. Skipping the interface</b><br />
<br />
If you are a beginner, you might be tempted to skip the interface and just implement <code>setKeeper(ZooKeeper keeper)</code> method in the <code>Koala</code>. Do not do that - do not trust the <code>Koala</code><br />
<br />
The <code>Koala</code> or any Observable is not supposed to have full access to its Observer. Eventually someone is going to add some methods to the <code>ZooKeeper</code> that are too tempting for the <code>Koala</code>, like <code>tieYourShoeLacesTogether</code>. No <code>Koala</code> would miss that one. Even if you can keep yourself from calling those methods, the future maintenance person will not hesitate. If he can do something, he will.<br />
<br />
<b>2. Forgetting to synchronize when refactoring the code</b><br />
<br />
Sometimes you do need to refactor the code later and add a list of Observers. You might be tempted to just add a <code>List</code> to hold the Observers and be done with it. Do not do that! The full-fledged Observer Pattern implementation needs synchronization.<br />
<br />
<br />
<span class="Apple-style-span" style="font-size: large;">Can you really do that? You'll have to implement the Observer Pattern sooner or later!</span><br />
<br />
Well, it depends on the case. I have been using this deprecated pattern for over 5 years. I can still count with my one hand fingers the times that I needed to refactor the code to use a real Observer Pattern. Usually people have great plans for the future, but they never get implemented. You should prepare for the future, but never implement things that are not really needed now.<br />
<br />
In most cases the Observable does just fine with one Observer. Sometimes there are cases where more Observers are needed, but this degenerated pattern is easily updated by storing the observers in a list and adding <code>addObserver</code> method. That will work as long as the Observers are added during initialization and synchronization is not needed. And with the <code><a href="http://download.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html#synchronizedList(java.util.List)">Collections.synchronizedList(List list)</a></code> you will add the synchronization in a minute, if needed.<br />
<br />
Sometimes you will have a case where the Observers are added and removed on the fly from different threads and you need to make conditional notifications and/or store different types of Observers. Those cases are rare, but sometimes do happen. For those ones, you need a more complete implementations of the pattern. Let's take a look at those in the next parts.<br />
<br />Jaanahttp://www.blogger.com/profile/09071115694773187816noreply@blogger.com0tag:blogger.com,1999:blog-7653287822664293054.post-64518760254161767262011-10-29T10:18:00.000+03:002011-10-29T10:18:59.514+03:00Who is my Koala keeper?<br />
<br />
This post contains answers to the puzzler presented in my previous post <a href="http://beyond100classes.blogspot.com/2011/10/observer-part-i-how-to-mess-up-your.html">Observer Pattern: Part I - How to mess up your code with it</a>.<br />
<br />
<br />
All the code presented in the previous post is here:<br />
<br />
<ul>
<li><a href="http://code.google.com/p/beyondhc/source/browse/trunk/beyondhc/src/test/java/org/beyondhc/lessons/observer/BadObserver.java">BadObserver.java</a> - example of the basic Observer implementation</li>
<li><a href="http://code.google.com/p/beyondhc/source/browse/trunk/beyondhc/src/test/java/org/beyondhc/lessons/observer/BadObserverLater.java">BadObserverLater.java</a> - example for the puzzler</li>
</ul>
<br />
<br />
<span class="Apple-style-span" style="font-size: large;">What was wrong with the code?</span><br />
<br />
There were 3 things wrong with the code:<br />
<ol>
<li>The <code>WaterPipe</code> is not getting fixed</li>
<li>The <code>Boss</code> is observing the <code>Koala</code>s, but when they are hungry, all he does is complain</li>
<li>Whenever the <code>ZooKeeper</code> feeds a <code>Koala</code>, the <code>Boss</code> is notified twice</li>
</ol>
<div>
<b><br /></b><br />
<span class="Apple-style-span" style="font-size: large;">Was the <code>Boss</code> supposed to observe the <code>Koala</code>?</span></div>
<div>
<br /></div>
<div>
Well, we have no way of knowing for sure just by looking at the code. I try to avoid puzzles with no clear answer in the future, but there was no going around for this one. When you do not type strictly, you just miss the information in the code if something goes wrong.<br />
<br /></div>
<div>
The initial though you probably had is that it probably is a mistake to add the <code>Boss</code> as the observer for the <code>Koala</code>, because he does not have the Koala-feeding code in his <code>update</code> method. But you cannot know for sure.<br />
<br /></div>
It is also possible (though not probable) that, for example, the <code>Boss</code> was supposed to feed the <code>Koala</code>s while the <code>ZooKeeper</code> is on vacation, but the implementation was never completed. We would need to search through the code and try to find if <code>ZooKeeper</code> ceases to observe the <code>Koala</code>s at some point. If we find such a code, we must fix the <code>Boss</code> so that he can feed the <code>Koala</code>s. If the <code>ZooKeeper</code> is available all the time, we can assume that the <code>Boss</code> should probably not be observing the <code>Koala</code>s. <b><br /></b><br />
<br />
<br />
<span class="Apple-style-span" style="font-size: large;">Could something like this really happen? Why would someone code something like this?</span><br />
<div>
<br /></div>
<div>
Yes, and no. </div>
<div>
<br /></div>
<div>
The broken pipe was my own addition. As we do not have a complex subject and 10.000-50.000 lines of code here, I needed some distraction for you. I do not think it is a common mistake to totally mix up the observers like that. That type of mistake is possible, but as the pipe-fixing functionality would stop working altogether, it would be caught in the testing quite fast and thus the error would not survive long. </div>
<div>
<br /></div>
<div>
But what happened with the <code>Boss</code> is real. I have fixed a similar bug. One of the nasty things about this pattern implementation is that the only reference to <code>update</code> method is in the <code>java.util.Observable</code>. The codebase had about 10 different <code>Observer</code>s and I had to check through them all while I tried to find out who should observe who. Only after that was clear, was I able to concentrate on trying to find out what is wrong. The update method having and argument of <code>Object</code> array with four unknown <code>Boolean</code> and <code>Integer</code> parameters did not help either. </div>
<div>
<br /></div>
<div>
Finally I came into conclusion that probably the <code>Boss</code> and the <code>ZooKeeper</code> had originally both been observing the <code>Koala</code>. At some point someone had thought that it is better that the <code>ZooKeeper</code> keeps the <code>Boss</code> informed. And while he remembered to remove the Koala-feeding code from the <code>Boss</code>, he did not remember that the <code>Boss</code> was still added as <code>Observer</code> for <code>Koala</code>s. We were getting quite a lot of extra notifications! </div>
<div>
<br /></div>
<div>
While the similar situation could have occurred with better implementation of the Observer Pattern, it could not have happened by mistake. If strict types would have been used, the programmer would have gotten a compilation failure for trying to add the <code>Boss</code> as an observer for <code>Koala</code>.<br />
<br />
In the next part of this series, I'll show you better ways to implement the Observer Pattern.<br />
<br />
<br />
<br /></div>
<div>
<br /></div>
<div>
<br /></div>Jaanahttp://www.blogger.com/profile/09071115694773187816noreply@blogger.com0tag:blogger.com,1999:blog-7653287822664293054.post-31897050411641551322011-10-22T13:30:00.001+03:002011-10-24T16:54:54.391+03:00Observer: Part I - How to mess up your code with it<br />
<a href="http://www.dofactory.com/Patterns/PatternObserver.aspx">The Observer pattern </a>is one of the patterns published in the Design Patterns book by the Gang of Four. It is needed when you have an object that changes it's state and you want other objects to notice the change.<br />
<br />
If you are programming Java user interfaces you cannot really avoid this pattern. The whole Java event handling is based on it. So whenever you are writing event listeners for Swing components, you are actually using this pattern.<br />
<br />
But Java also offers an implementation of the <a href="http://download.oracle.com/javase/6/docs/api/java/util/Observer.html"><code>Observer</code></a> interface and an <a href="http://download.oracle.com/javase/6/docs/api/java/util/Observable.html"><code>Observable</code></a> class to go with the interface. The problem with the Java <code>Observer</code> and <code>Observable</code> is that they were written before the Generics and so they use plain <code>Object</code>s to pass information. While that is not a problem in small hobby projects, it may lead to disasters in larger applications.<br />
<i><br /></i><br />
<i>If you want to create easily maintainable code, you need to enforce the strong type checking that Java offers</i>.<br />
<br />
I guess most of you have heard that before. But maybe some of you have not seen what may happen when that rule is broken. And that is what I am about to demonstrate today. This is a beginner-level article. If you have already messed up your code by violating the rule and always try to avoid casting objects in your code, you might want to just quickly browse through the code and read the puzzler at the end of the post.<br />
<br />
<br />
<span class="Apple-style-span" style="font-size: large;">How to mess up your code with Java Observer</span><br />
<br />
I am going to demonstrate the problem with a simple example from the Koala Zoo. In the very first version of the Koala Zoo we have just a <code>Koala</code> and a <code>ZooKeeper</code>, who gives food to the <code>Koala</code> when it is hungry.<br />
<br />
Let's start by implementing the <code>Koala</code> using the Java <code>Observable</code>:<br />
<pre class="stylecode"> public class Koala extends Observable {
public void setHungry(final boolean isHungry) {
setChanged();
notifyObservers(isHungry);
}
@Override
public String toString() {
return "koala";
}
}
</pre>
<br />
There we go! In real life the <code>Koala</code> class would probably be a bit more complex, but this is enough for our purposes. As you notice, <code>Observable</code> is a class and needs to be extended by our <code>Koala</code>.<br />
<br />
Let's continue and create our <code>Observer</code>, the <code>ZooKeeper</code>. <code>Observer</code> is an interface with a single method for getting updates from the <code>Observable</code>:<span class="Apple-style-span" style="font-family: monospace; white-space: pre;"> </span><br />
<pre class="stylecode"> public class ZooKeeper implements Observer {
@Override
public void update(final Observable animal, final Object arg) {
if (arg instanceof Boolean) {
final boolean isHungry = (Boolean) arg;
if (isHungry) {
LOGGER.info("Oh, the " + animal
+ " is hungry. I'll go into the cage and "
+ "give some eucalyptus to the little fella!");
}
}
}
}</pre>
<br />
Our <code>Observable</code> and <code>Observer</code> are ready to go, let's test how they work:<br />
<pre class="stylecode"> public void testKoalaGetsFood() {
final LogMsgCaptor logMsgCaptor = new LogMsgCaptor(LOGGER);
final Koala koala = new Koala();
final ZooKeeper zooKeeper = new ZooKeeper();
koala.addObserver(zooKeeper);
koala.setHungry(true);
assertEquals("The zookeeper should get notified",
"Oh, the koala is hungry. I'll go into the cage and "
+ "give some eucalyptus to the little fella!",
logMsgCaptor.getMessage());
}
</pre>
<br />
<a href="http://code.google.com/p/beyondhc/source/browse/trunk/beyondhc/src/test/java/org/beyondhc/test/LogMsgCaptor.java"><code>LogMsgCaptor</code></a> is a <a href="http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html">Mockito</a>-based helper class that I wrote to collect logged messages so that I can test what was logged. <code>Assert.assertEquals</code> comes from JUnit and it makes our test case fail if the message logged does not match to what we expected.<br />
<br />
As we can see, the code works nicely and <code>ZooKeeper</code> is able to keep the <code>Koala</code> stuffed with eucalyptus. But things are going to change when the code evolves.<br />
<br />
The Zoo is growing and getting new animals. Introduce the <code>Tiger</code>!<br />
<pre class="stylecode"> public class Tiger extends Observable {
public void setHungry(final boolean isHungry) {
setChanged();
notifyObservers(isHungry);
}
@Override
public String toString() {
return "tiger";
}
}
</pre>
<br />
At this point I might spare a thought on whether I could use a common superclass called <code>Animal</code>. But as it's easy to refactor later and pull the methods up, I am not going to do that now.<br />
<br />
The <code>Tiger</code> observable is ready to use, but we have not made any changes to our <code>Observer</code>, the <code>ZooKeeper</code>. <i>The nasty thing is that we can actually add the <code>ZooKeeper</code> as an observer for <code>Tiger</code> already and we get no compilation errors when we compile the code</i>. Huh? The <code>ZooKeeper</code> is an observer for <code>Koala</code>, and as the update method is passing <code>Object</code>s as arguments, compiler have no way to know that the method is not implemented properly.<br />
<br />
That means we need to REMEMBER to update the <code>ZooKeeper</code>'s <code>update</code> method, so that he knows how the <code>Tiger</code> needs to be feed. But hey, that's no problem at all. I have great memory! If I sometimes forget my keys or the dinner or my pants or something it is just because I am thinking something else. But enough blabbering, let's have a coffee break. I suggest you to have a cup too!<br />
<div>
<br /></div>
Are you back yet? Where were we? Yeah, the <code>Tiger</code>. Let's continue and implement our new test case, the one where the <code>ZooKeeper</code> is feeding the <code>Tiger</code>:<br />
<pre class="stylecode"> public void testTiggerGetsFood() {
final LogMsgCaptor logMsgCaptor = new LogMsgCaptor(LOGGER);
final Tiger tigger = new Tiger();
final ZooKeeper zooKeeper = new ZooKeeper();
tigger.addObserver(zooKeeper);
tigger.setHungry(true);
// As this test goes through OK, we forgot to update the ZooKeeper
assertEquals("Hmmm. Should the zookeeper go into the cage?",
"Oh, the tiger is hungry. I'll go into the cage and "
+ "give some eucalyptus to the little fella!",
logMsgCaptor.getMessage());
};
</pre>
Oh well, what do you know... I'll fix the code in a minute...<br />
<br />
I know that at this point some of you are thinking that this is not a big deal. But as time goes by and code gets filled up with little slips like the one I made above, results can be... interesting.<br />
<br />
Let me show you an example with a little puzzler.<br />
<br />
<br />
<span class="Apple-style-span" style="font-size: large;">Puzzler: Koala Zoo after 2 years</span><br />
<br />
The application has expanded and the Zoo now has new personnel. The <code>ZooKeeper</code> has been changed, and he has a <code>Boss</code> to report to:<br />
<pre class="stylecode"> public class Boss implements Observer {
@Override
public void update(final Observable observable, final Object arg) {
if (observable instanceof ZooKeeper) {
((ZooKeeper) observable).getStatusReport();
}
LOGGER.info("I hate being bugged with little things");
}
}</pre>
<br />
We can see that the <code>ZooKeeper</code> has become <code>Observable</code> too. Here is the new code for the <code>ZooKeeper</code>:<br />
<pre class="stylecode"> public class ZooKeeper extends Observable implements Observer {
public void getStatusReport() {
LOGGER.info("Well, I have taken care of everything");
}
@Override
public void update(final Observable observable, final Object arg) {
final boolean argIsTrue = Boolean.TRUE.equals(arg);
if (observable instanceof Koala && argIsTrue) {
LOGGER.info("The lazy critter is hungry again, I cannot believe how much it eats");
}
else if (observable instanceof WaterPipe && argIsTrue) {
LOGGER.info("I'll do what needs to be done");
}
if (argIsTrue) {
setChanged();
notifyObservers();
}
}
}</pre>
<br />
Oh, it seems that the <code>ZooKeeper</code> now observers a <code>WaterPipe</code> too. But what is the argument? Lets check that out the <code>WaterPipe</code> to find out:<br />
<pre class="stylecode"> public class WaterPipe extends Observable {
public void setBroken(final boolean isBroken) {
setChanged();
notifyObservers(isBroken);
}
@Override
public String toString() {
return "watering system";
}
}</pre>
<br />
Oh, the argument is telling if the pipe is broken!<br />
Let's see how all these classes are used:<br />
<pre class="stylecode"> final List<koala> fifteenKoalas = initKoalas();
final WaterPipe pipe = new WaterPipe();
final ZooKeeper zooKeeper = new ZooKeeper();
final Boss boss = new Boss();
zooKeeper.addObserver(boss);
pipe.addObserver(boss);
for (final Koala koala : fifteenKoalas) {
koala.addObserver(boss);
koala.addObserver(zooKeeper);
}</koala></pre>
<br />
And as you might guess, this code is not working.<br />
<br />
<b>What is wrong and how would you fix it? Is the <code>Boss</code> supposed to observe the <code>Koalas</code>?</b><br />
<div>
<br /></div>
I'll tell you the answers in the next post.<br />
<div>
<br /></div>
<div>
<br />
<br />
<pre class="stylecode"></pre>
</div>Jaanahttp://www.blogger.com/profile/09071115694773187816noreply@blogger.com0tag:blogger.com,1999:blog-7653287822664293054.post-51694963997584107782011-10-15T12:20:00.000+03:002011-10-15T12:20:39.600+03:00Introduction and policy<div>
This blog will contain little lessons about things that may cause problems in the context of larger code-bases. I will present you coding mistakes, bad practices and a way to implement the same thing in a better way. I will also present you some patterns that are widely promoted, but are often implemented badly by beginners. I will present stuff that is just fine in little home projects or school-work, but in the bigger projects cause a major headache in the future for the maintenance person. </div>
<div>
<br /></div>
<div>
I am a Java specialist with over 10 years of experience in working with large code-bases. I have started some of those myself from the scratch, some I have just maintained. But in every case there has been so much to learn. </div>
<div>
<br /></div>
<div>
The best way of learning is by mistake. Most of the stories told here are based on my own mistakes and bad practices. However, our own mistakes and bad habits are often invisible for us, at least for the first 1-2 years after the program has been made. Thus, I would never have learned so much without my dear colleagues. If you know me and see a mistake that was made by you, be proud. You have helped me to learn, and now you are helping others to learn. </div>
<div>
<br /></div>
There is a companion code-base for this blog, called <a href="http://code.google.com/p/beyondhc">beyondhc</a>. All the code snippets and classes presented in this blog can be found there. As most of the large code-bases are commercial, the code is published with Eclipse Public License 1.0 so that you may really use what you find. <div>
<br /></div>
<div>
I respect my employer and do not use any project code in this blog. As the stories are based on what I have learned while working, the classes may have some resemblance to existing project code (dead or alive). But I assure that any such resemblance is purely coincidental. Each and every class presented here is written from the scratch - nothing is copied from existing projects.</div>
<div>
<br /></div>
<div>
And one last thing. I am not going to publish regularly, no-no. I'll just publish when I have something new to say. However, once I start a new series, you may expect the next parts to appear maybe once in a week (or two weeks) until the series is finished. </div>Jaanahttp://www.blogger.com/profile/09071115694773187816noreply@blogger.com0