<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>blog.smart-java.nl &#187; Java language</title>
	<atom:link href="http://blog.smart-java.nl/blog/index.php/category/javalanguage/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.smart-java.nl/blog</link>
	<description>Ordina J-Technologies - Java Blog</description>
	<lastBuildDate>Wed, 05 May 2010 20:06:33 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Immutable lists</title>
		<link>http://blog.smart-java.nl/blog/index.php/2010/03/26/immutable-lists/</link>
		<comments>http://blog.smart-java.nl/blog/index.php/2010/03/26/immutable-lists/#comments</comments>
		<pubDate>Fri, 26 Mar 2010 15:03:51 +0000</pubDate>
		<dc:creator>Pieter van der Meer</dc:creator>
				<category><![CDATA[Concurrency]]></category>
		<category><![CDATA[Java language]]></category>
		<category><![CDATA[patterns]]></category>

		<guid isPermaLink="false">http://blog.smart-java.nl/blog/?p=1048</guid>
		<description><![CDATA[The last couple of years there is more and more talk about concurrency. One of the main issues is the access data from the various threads that you have running.
Brian Goetz has a simple statement on how to solve this:  Use immutable objects where ever possible. Although true it is not always as simple to [...]]]></description>
			<content:encoded><![CDATA[<p>The last couple of years there is more and more talk about concurrency. One of the main issues is the access data from the various threads that you have running.</p>
<p>Brian Goetz has a simple statement on how to solve this:  <em>Use immutable objects where ever possible. </em>Although true it is not always as simple to implement your data structures immutable. especially when you are working with Collections (List/Set/Map).</p>
<p>Making the collection variable immutable is easy,<br />
<span id="more-1048"></span></p>
<pre class="brush: java">class finalSet {
  private final Set theSet;
  public finalSet(Set theSet) {
    this.theSet = theSet;
  }

  public Set getSet() {
    return this.theSet;
  }
}</pre>
<p>With this it is not possible the change the value of the Set parameter. But when retrieving the Set with <em>getSet </em>you are still able to modify the content of the set.  This effectively means that the set you attempted to make immutable is still mutable.</p>
<p>The documentation of the <a href="http://java.sun.com/javase/6/docs/technotes/guides/collections/overview.html">Collections Framework</a> does not provide an answer on how to make the collection immutable. they speak just a little about the class <span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; line-height: 18px; font-size: 12px; white-space: pre;">Collections<span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; line-height: 19px; white-space: normal; font-size: 13px;">. </span></span></p>
<p><span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; line-height: 18px; font-size: 12px; white-space: pre;"><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; line-height: 19px; white-space: normal; font-size: 13px;">Taken from the documentation page:</span></span></p>
<blockquote><p>The general-purpose implementations support all of the <em>optional operations</em> in the collection interfaces, and have no restrictions on the elements they may contain. They are unsynchronized, but the <code>Collections</code> class contains static factories called <a href="http://java.sun.com/javase/6/docs/api/java/util/Collections.html#synchronizedCollection(java.util.Collection)"><em>synchronization wrappers</em></a> that may be used to add synchronization to many unsynchronized collections. All of the new implementations have <em>fail-fast iterators</em>, which detect illegal concurrent modification, and fail quickly and cleanly (rather than behaving erratically).</p></blockquote>
<p>What they say there is a Collections class that does all kind of things for you, mainly synchronization, but do not really say what else it can do for you. As you might guess it provides with methods to make you list immutable!</p>
<p>Take a look at the <a href="http://java.sun.com/javase/6/docs/api/java/util/Collections.html">Collections javadoc</a> (without explicitly searching for this class its hard to find).<br />
It gets interesting when you scroll down to the methods that start with</p>
<pre>unmodifiable</pre>
<p>. For all the base interface from the <a href="http://java.sun.com/javase/6/docs/technotes/guides/collections/overview.html">Collections Framework</a> there is a method to make it unmodifiable. hey wait a second: unmodifiable aint that the same as immutable? To my humble opinion it does. So Java does provide a out of the box solution to make a collection immutable!</p>
<p>this code snippet proves that it works:</p>
<pre class="brush: java">import org.junit.Test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.HashSet;

/**
 * Simple Unit test for immutability
 */
public class ListTest {

    /**
     * The actual testing for a List
     */
    @Test (expected = UnsupportedOperationException.class)
    public void immutableList() {
        //Create a simple mutable list
        List mutableList = new ArrayList();
        mutableList.add("A");
        mutableList.add("B");
        //Make this immutable
        List immutableList = Collections.unmodifiableList(mutableList);

        //Try and set the value of an element in the list
        immutableList.set(1, "X");
    }

    /**
     * The actual testing for a Set
     */
    @Test (expected = UnsupportedOperationException.class)
    public void immutableSet() {
        //Create a mutable set
        Set mutableSet = new HashSet();
        mutableSet.add("A");
        mutableSet.add("B");
        //Change it to immutable
        Set immutableSet = Collections.unmodifiableSet(mutableSet);

        //Try and add an element to it.
        immutableSet.add("X");
    }
}</pre>
<p>When you run the unit tests both the tests will succeed.</p>
<p><strong>Conclusion</strong>:<br />
making a list immutable ain&#8217;t that hard <img src='http://blog.smart-java.nl/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  Just be aware i say nothing about the elements in the list, they must be immutable as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smart-java.nl/blog/index.php/2010/03/26/immutable-lists/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Unit Testing a Bean Validation ConstraintValidator</title>
		<link>http://blog.smart-java.nl/blog/index.php/2010/03/12/unit-testing-a-bean-validation-constraintvalidator/</link>
		<comments>http://blog.smart-java.nl/blog/index.php/2010/03/12/unit-testing-a-bean-validation-constraintvalidator/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 15:27:16 +0000</pubDate>
		<dc:creator>Jan-Kees van Andel</dc:creator>
				<category><![CDATA[Java API]]></category>
		<category><![CDATA[Java EE]]></category>
		<category><![CDATA[Java language]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[annotations]]></category>
		<category><![CDATA[bean validation]]></category>
		<category><![CDATA[ConstraintValidator]]></category>
		<category><![CDATA[Dynamic Proxies]]></category>
		<category><![CDATA[JUnit]]></category>
		<category><![CDATA[Mockito]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://blog.smart-java.nl/blog/?p=976</guid>
		<description><![CDATA[I&#8217;ve been playing a bit with Bean Validation and thought I found an issue: Unit testing a ConstraintValidator. Specifically, parametrized ConstraintValidators.
First, what&#8217;s a parametrized ConstraintValidator? Simple, a Validator that takes a parameter to do its job. A simple example is a length validator that takes the minimum and maximum length as parameters and validates if [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been playing a bit with Bean Validation and thought I found an issue: Unit testing a ConstraintValidator. Specifically, parametrized ConstraintValidators.</p>
<p>First, what&#8217;s a parametrized ConstraintValidator? Simple, a Validator that takes a parameter to do its job. A simple example is a length validator that takes the minimum and maximum length as parameters and validates if the value is between those two.</p>
<p>Parametrized ConstraintValidators are everywhere, even Bean Validation itself contains them. For example: @Min(length) and @Max(length), but also normal ConstraintValidators, like @NotNull where you can customize the error message. However, this error message parameter is not very interesting with regards to unit testing individual ConstraintValidators, because the message is generated by the Bean Validation framework.</p>
<p>For example, consider this ConstraintValidator, incl. corresponding annotation:</p>
<pre><script type="syntaxhighlighter" class="brush: java">
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = CreditCardExpiryYearValidator.class)
public @interface CreditCardExpiryYear {
    int expirationInYears() default 10;
    String message() default "{validation.CreditCardExpiryYear.message}";
}

public class CreditCardExpiryYearValidator implements ConstraintValidator&lt;CreditCardExpiryYear, Integer&gt; {
    private volatile int expirationInYears;
    public void initialize(CreditCardExpiryYear constraint) {
        this.expirationInYears = constraint.expirationInYears();
    }

    public boolean isValid(Integer year, ConstraintValidatorContext context) {
        final int nowYear = Calendar.getInstance().get(Calendar.YEAR);
        return year != null
            &amp;&amp; year &lt; nowYear + expirationInYears;
    }
}
</script></pre>
<p>In the future, Bean Validation may become the core mechanism for ensuring correctness in your system. For example, JPA 2.0 leverages Bean Validation annotations to generate additional DDL statements and JSF 2.0 automatically uses Bean Validation when it&#8217;s available. Note: JSF 2.0 uses a new concept, called &#8220;default validators&#8221; to implement this. A default validator is invoked on every input component on a postback.</p>
<p>But, how do we test this stuff? After all, you can&#8217;t instantiate an annotation.</p>
<p>I currently have 4 options:</p>
<ul>
<li><a href="#reflection">Using reflection to use a declared annotation</a></li>
<li><a href="#implementation">Custom annotation implementation</a></li>
<li><a href="#dynamic_proxies">Dynamic proxies</a></li>
<li><a href="#mockito">Mocking, for example using Mockito</a></li>
</ul>
<p><b><a name="reflection">Using a declared annotation</a></b><br />
The first attempt is shown below. Here, I simply declare the annotation in my test case on a dummy instance field (an annotation doesn&#8217;t live on its own) and look it up using reflection. This way, Java takes care of instantiating and initializing the annotation.</p>
<pre><script type="syntaxhighlighter" class="brush: java">
public class CreditCardExpiryYearValidatorTest {

    @CreditCardExpiryYear(expirationInYears = 5)
    int expiryAfter5Years;

    @CreditCardExpiryYear
    int expiryAfter10Years;

    private int currentYear;

    @Before
    public void setUp() throws Exception {
        currentYear = Calendar.getInstance().get(Calendar.YEAR);
    }

    @Test
    public void testIsValid_DefaultExpiration() throws Exception {
        CreditCardExpiryYearValidator val = new CreditCardExpiryYearValidator();
        val.initialize(getFieldAnnotation(this, "expiryAfter10Years", CreditCardExpiryYear.class));

        boolean b = val.isValid(currentYear + 5, null);

        assertTrue(b);
    }

    @Test
    public void testIsValid_Configure5Years() throws Exception {
        CreditCardExpiryYearValidator val = new CreditCardExpiryYearValidator();
        val.initialize(getFieldAnnotation(this, "expiryAfter5Years", CreditCardExpiryYear.class));

        boolean b = val.isValid(currentYear + 6, null);

        assertFalse(b);
    }
}
</script></pre>
<p>I personally quite like this approach. The test data is inside the test case. Unfortunately not in the test method, that would be better, but since you can&#8217;t put annotations everywhere in your code, it&#8217;s not easy to implement this decently.</p>
<p>So let&#8217;s look at the next one&#8230;</p>
<p><b><a name="implementation">Custom annotation implementation</a></b><br />
Since Java annotations are just a special case of interfaces, they should be fairly straightforward to implement. However, for some reason, I didn&#8217;t know this until recently. But it&#8217;s actually not different from any other interface implementation. See for yourself.</p>
<pre><script type="syntaxhighlighter" class="brush: java">
public class CreditCardExpiryYearValidatorTest {

    private int currentYear;

    @Before
    public void setUp() throws Exception {
        currentYear = Calendar.getInstance().get(Calendar.YEAR);
    }

    @Test
    public void testIsValid_CustomAnnotationImpl() throws Exception {
        CreditCardExpiryYearValidator val = new CreditCardExpiryYearValidator();
        val.initialize(new CreditCardExpiryYearImpl());

        boolean b = val.isValid(currentYear + 6, null);

        assertFalse(b);
    }
}
class CreditCardExpiryYearImpl implements CreditCardExpiryYear {
    public int expirationInYears() { return 5; }
    public String message() { return "hello"; }
    public Class&lt;? extends Annotation&gt; annotationType() { return CreditCardExpiryYear.class; }
}
</script></pre>
<p>Nothing special, right? But I don&#8217;t really like it. I could have also written it inline, but I don&#8217;t like that either:</p>
<pre><script type="syntaxhighlighter" class="brush: java">
@Test
public void testIsValid_CustomAnnotationImplInline() throws Exception {
    CreditCardExpiryYearValidator val = new CreditCardExpiryYearValidator();
    val.initialize(new CreditCardExpiryYear() {
        public Class&lt;? extends Annotation&gt; annotationType() { return CreditCardExpiryYear.class; }
        public String message() { return ""; }
        public int expirationInYears() { return 5; }
    });

    boolean b = val.isValid(currentYear + 6, null);

    assertFalse(b);
}
</script></pre>
<p>I think the above one looks like garbage. So this is also a no-go.</p>
<p><b><a name="dynamic_proxies">Dynamic proxies</a></b><br />
Java itself uses dynamic proxies at runtime to instantiate annotations. So why not also use a Proxy to mock the annotation? See for yourself. </p>
<pre><script type="syntaxhighlighter" class="brush: java">
@Test
public void testIsValid_DynamicProxy() throws Exception {
    CreditCardExpiryYearValidator val = new CreditCardExpiryYearValidator();
    CreditCardExpiryYear annotation = (CreditCardExpiryYear)
            Proxy.newProxyInstance(
                    this.getClass().getClassLoader(),
                    new Class&lt;?&gt;[] { CreditCardExpiryYear.class },
                    new InvocationHandler() {
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            return 5;
        }
    });
    val.initialize(new CreditCardExpiryYearImpl());
    boolean b = val.isValid(currentYear + 6, null);

    assertFalse(b);
}
</script></pre>
<p>However inline, the implementation looks very clumsy. Unfortunately this is probably as simple as it can get, since you DO need to define the inner class.</p>
<p>And it will become even worse when there are multiple parameters on the bean, since you need to check which method is invoked. This will make the implementation even worse.</p>
<p><b><a name="mockito">Mocking using Mockito</a></b><br />
But, creating and configuring proxies, isn&#8217;t this what mocking libraries do? Exactly, let&#8217;s try.</p>
<pre><script type="syntaxhighlighter" class="brush: java">
@Test
public void testIsValid_Mockito() throws Exception {
    CreditCardExpiryYearValidator val = new CreditCardExpiryYearValidator();
    CreditCardExpiryYear annotation = mock(CreditCardExpiryYear.class);
    when(annotation.expirationInYears()).thenReturn(5);

    val.initialize(annotation);
    boolean b = val.isValid(currentYear + 6, null);

    assertFalse(b);
}
</script></pre>
<p>This looks pretty nice. And it scales well with multiple attributes.</p>
<p>I only doubt it will be the nicest solution when the annotations become more complex. I really don&#8217;t like annotations that contain annotation parameters. Or even worse, arrays of annotation parameters. But reality is, they exist. And if they exist, they also need to be tested. But, OTOH, people who nest annotations probably don&#8217;t mind unreadable unit tests. <img src='http://blog.smart-java.nl/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smart-java.nl/blog/index.php/2010/03/12/unit-testing-a-bean-validation-constraintvalidator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>java.util.Calendar.getActualMaximum returns strange results</title>
		<link>http://blog.smart-java.nl/blog/index.php/2010/01/20/java-util-calendar-getactualmaximum-returns-strange-results/</link>
		<comments>http://blog.smart-java.nl/blog/index.php/2010/01/20/java-util-calendar-getactualmaximum-returns-strange-results/#comments</comments>
		<pubDate>Wed, 20 Jan 2010 15:55:15 +0000</pubDate>
		<dc:creator>Peter Schuler</dc:creator>
				<category><![CDATA[Java API]]></category>
		<category><![CDATA[Java language]]></category>
		<category><![CDATA[Bug]]></category>
		<category><![CDATA[Calendar]]></category>

		<guid isPermaLink="false">http://blog.smart-java.nl/blog/?p=643</guid>
		<description><![CDATA[At the end of last year I encountered something odd in the java.util.Calendar. Now is odd behavior nothing to be surprised of in the Java Calendar but this particular oddness was really hard to spot.
I will therefore share it with you.
The code
Let&#8217;s first look a some code dealing with getting the last day of the [...]]]></description>
			<content:encoded><![CDATA[<p>At the end of last year I encountered something odd in the java.util.Calendar. Now is odd behavior nothing to be surprised of in the Java Calendar but this particular oddness was really hard to spot.</p>
<p>I will therefore share it with you.</p>
<p><strong>The code</strong></p>
<p>Let&#8217;s first look a some code dealing with getting the last day of the month:</p>
<pre class="brush:java">public class CalendarTest {
  public static void main(String[] args) {
    Calendar c = Calendar.getInstance();
    c.set(Calendar.MONTH, Calendar.FEBRUARY);
    int maxDayOfMonth = c.getActualMaximum(Calendar.DAY_OF_MONTH);

    System.out.println("last day of month = " + maxDayOfMonth);
  }
}</pre>
<p>Please read the java doc for <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Calendar.html#getActualMaximum(int)">Calendar.getActualMaximum()</a>:</p>
<blockquote><p>Returns the maximum value that the specified calendar field could have, given the time value of this Calendar. For example, the actual maximum value of the MONTH field is 12 in some years, and 13 in other years in the Hebrew calendar system.</p></blockquote>
<p>So the code above can print two different values right &#8230;? 28 or 29 depending on the whether this year is a leap year. As you could have guessed that is another unexpected possibility. I can also print 31. Yes&#8230; really.</p>
<p>I all depends on the date on which this code is executed.</p>
<p>The problem is that Calendar.getInstance() will return a Calendar filled with the current date/time. Let&#8217;s assume the above code runs on the last day of January. The call to getInstance() will return 31-01-2009. The next step puts the month to February. This will result in a overflow as 31-02-2009 is invalid. Because of this Calendar will move the date to 3-03-2000. And March has 31 days.</p>
<p>There is a <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4452473">bug report (status: Closed, Not a Defect</a>) in the SDN which told me that the observed behavior was correct. I was not the <a href="http://forums.sun.com/thread.jspa?threadID=5422080">first</a> person surprised by this and I&#8217;m guessing I will not be the last.</p>
<p>I was &#8230;</p>
<ol>
<li>&#8230; lucky I wrote a decent unit test.</li>
<li>&#8230; lucky to be running said unit test om 31 December.</li>
<li>&#8230; unlucky for having to work on the last day of the year.</li>
</ol>
<p>Otherwise the bug I created would properly have slipped through the QA cycles and would have ended up in production. There it would only be visible on the last three days of every month if someone would specify a date in February.</p>
<p><strong>What about lenient?</strong><br />
The Calendar.setLenient function does protect against invalid input. Let&#8217;s quote the the <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Calendar.html#setLenient(boolean)">Calendar java doc</a> about Leniency:</p>
<blockquote><p><strong>Leniency</strong><br />
Calendar has two modes for interpreting the calendar fields, lenient and non-lenient. When a Calendar is in lenient mode, it accepts a wider range of calendar field values than it produces. When a Calendar recomputes calendar field values for return by get(), all of the calendar fields are normalized. For example, a lenient GregorianCalendar interprets MONTH == JANUARY, DAY_OF_MONTH == 32 as February 1.</p>
<p>When a Calendar is in non-lenient mode, it throws an exception if there is any inconsistency in its calendar fields. For example, a GregorianCalendar always produces DAY_OF_MONTH values between 1 and the length of the month. A non-lenient GregorianCalendar throws an exception upon calculating its time or calendar field values if any out-of-range field value has been set.</p></blockquote>
<p>So lenient does protect against the programmer/user creating a invalid date in a way that the following code will result in an exception:</p>
<pre class="brush:java">    Calendar c = Calendar.getInstance();
    c.setLenient(false);
    c.set(Calendar.MONTH, Calendar.FEBRUARY);
    c.set(Calendar.DAY_OF_MONTH, 31);
    System.out.println(c.getTime());</pre>
<p>But the exception is only thrown when c.getTime() is called. Calls to getActualMaximum() still work and return 31. So lenient is not useful here.</p>
<p><strong>Lessons learned</strong></p>
<p>The quick fix for this problem is to set the DAY_OF_MONTH to 1 (or any number between 1 and 28) <strong>before</strong> setting the month.</p>
<p>I also learned that Calendar.setLenient() will not protect you from this error. It will only stop you from getting an invalid Date. It does not protect against overflows.</p>
<p><strong>Sould I use JODA time?</strong></p>
<p>At the end of this post I have a question for you. I have no experience with JODA time always preferring to use the standard Date/Time API unless there was a problem. But perhaps I should reverse my views and use JODA time unless I&#8217;m not allowed too? What do you think &#8230; is it time to stop  using the default Calendar API and use JODA time instead? Or should I wait for Java 7 with <a href="http://jcp.org/en/jsr/detail?id=310">JSR 310</a>?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smart-java.nl/blog/index.php/2010/01/20/java-util-calendar-getactualmaximum-returns-strange-results/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Temporale data – deel 4: bitemporale collections</title>
		<link>http://blog.smart-java.nl/blog/index.php/2009/12/07/temporale-data-%e2%80%93-deel-4-bitemporale-collections/</link>
		<comments>http://blog.smart-java.nl/blog/index.php/2009/12/07/temporale-data-%e2%80%93-deel-4-bitemporale-collections/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 11:36:20 +0000</pubDate>
		<dc:creator>gnoij</dc:creator>
				<category><![CDATA[Algemeen]]></category>
		<category><![CDATA[Java language]]></category>
		<category><![CDATA[Tools/Frameworks]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[bitemporal pattern]]></category>
		<category><![CDATA[temporale data]]></category>

		<guid isPermaLink="false">http://blog.smart-java.nl/blog/?p=551</guid>
		<description><![CDATA[Het is alweer enige tijd geleden dat ik heb geschreven over temporale patterns. In dit deel wil ik het bitemporale pattern uitbreiden met bitemporale collections. Werd met de bitemporale property nog een enkele property historisch gemaakt, in dit deel maken we een lijst historisch. Dat wil zeggen dat er meerdere elementen van een historische lijst [...]]]></description>
			<content:encoded><![CDATA[<p>Het is alweer enige tijd geleden dat ik heb geschreven over <a href="http://blog.smart-java.nl/blog/index.php/2008/11/19/temporale-data-%e2%80%93-deel-1-de-concepten/">temporale patterns</a>. In dit deel wil ik het <a href="http://blog.smart-java.nl/blog/index.php/2008/12/22/temporale-data-%e2%80%93-deel-3-het-bitemporale-pattern/">bitemporale pattern</a> uitbreiden met bitemporale collections. Werd met de bitemporale property nog een enkele property historisch gemaakt, in dit deel maken we een lijst historisch. Dat wil zeggen dat er meerdere elementen van een historische lijst tegelijkertijd geldig kunnen zijn.</p>
<p>De klasse <code>BiTemporalObject</code> uit het derde deel blijft hetzelfde. En naast de <code>BiTemporalProperty</code> voor enkelvoudige historische relaties krijgen we nu ook een klasse <code>BiTemporalCollection</code> voor meervoudige historische relaties.</p>
<p><strong>BiTemporalCollection</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> BiTemporalCollection <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #003399;">List</span> alleHistorischeVersies <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ArrayList</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> BiTemporalCollection<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">List</span> getActueleVersies<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> getVersieOp<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">List</span> getVersieOp<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Date</span> registratieTijdstip, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Date</span> peilDatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">List</span><span style="color: #009900;">&#41;</span> CollectionUtils.<span style="color: #006633;">select</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">alleHistorischeVersies</span>, <span style="color: #000000; font-weight: bold;">new</span> Predicate<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> evaluate<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> object<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>BiTemporalObject<span style="color: #009900;">&#41;</span> object<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">isGeldigOp</span><span style="color: #009900;">&#40;</span>registratieTijdstip, peilDatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> voegActueleVersieToe<span style="color: #009900;">&#40;</span>BiTemporalObject actueleVersie<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>actueleVersie <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">IllegalArgumentException</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;actueleVersie is null&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">alleHistorischeVersies</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>actueleVersie<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> wijzigActueleVersie<span style="color: #009900;">&#40;</span>BiTemporalObject nieuweVersie, BiTemporalObject oudeVersie<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>nieuweVersie <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">IllegalArgumentException</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;nieuweVersie is null&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>oudeVersie <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">IllegalArgumentException</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;oudeVersie is null&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        beeindigVorigeVersie<span style="color: #009900;">&#40;</span>nieuweVersie, oudeVersie<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">alleHistorischeVersies</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>nieuweVersie<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">void</span> beeindigVorigeVersie<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> BiTemporalObject nieuweVersie, <span style="color: #000000; font-weight: bold;">final</span> BiTemporalObject oudeVersie<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        BiTemporalObject afTeVoerenVersie <span style="color: #339933;">=</span> zoekActueleVersie<span style="color: #009900;">&#40;</span>oudeVersie, nieuweVersie.<span style="color: #006633;">getIngangsdatum</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, nieuweVersie.<span style="color: #006633;">getOpvoerTijdstip</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
&nbsp;
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>afTeVoerenVersie <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">IllegalStateException</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Geen oude actuele versie gevonden!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        beeindigVersie<span style="color: #009900;">&#40;</span>afTeVoerenVersie, nieuweVersie.<span style="color: #006633;">getIngangsdatum</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, nieuweVersie.<span style="color: #006633;">getOpvoerTijdstip</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> beeindig<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> BiTemporalObject actueleVersie, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Date</span> einddatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        BiTemporalObject afTeVoerenVersie <span style="color: #339933;">=</span> zoekActueleVersie<span style="color: #009900;">&#40;</span>actueleVersie, einddatum, <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>afTeVoerenVersie <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">IllegalStateException</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Geen oude actuele versie gevonden!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        beeindigVersie<span style="color: #009900;">&#40;</span>afTeVoerenVersie, einddatum, <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> beeindig<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Date</span> einddatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">List</span> afTeVoerenVersies <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">List</span><span style="color: #009900;">&#41;</span> CollectionUtils.<span style="color: #006633;">select</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">alleHistorischeVersies</span>, <span style="color: #000000; font-weight: bold;">new</span> Predicate<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> evaluate<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> object<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                BiTemporalObject versie <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>BiTemporalObject<span style="color: #009900;">&#41;</span> object<span style="color: #339933;">;</span>
                <span style="color: #000000; font-weight: bold;">return</span> versie.<span style="color: #006633;">isGeldigOp</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, einddatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        CollectionUtils.<span style="color: #006633;">forAllDo</span><span style="color: #009900;">&#40;</span>afTeVoerenVersies, <span style="color: #000000; font-weight: bold;">new</span> Closure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> execute<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> input<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                beeindigVersie<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>BiTemporalObject<span style="color: #009900;">&#41;</span> input, einddatum, <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">void</span> beeindigVersie<span style="color: #009900;">&#40;</span>BiTemporalObject versie, <span style="color: #003399;">Date</span> einddatum, <span style="color: #003399;">Date</span> registratieTijdstip<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        BiTemporalObject kopieVersie <span style="color: #339933;">=</span> versie.<span style="color: #006633;">kopieer</span><span style="color: #009900;">&#40;</span>einddatum, registratieTijdstip<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">alleHistorischeVersies</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>kopieVersie<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> BiTemporalObject zoekActueleVersie<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> BiTemporalObject actueleVersie, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Date</span> peildatum, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Date</span> registratieTijdstip<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>BiTemporalObject<span style="color: #009900;">&#41;</span> CollectionUtils.<span style="color: #006633;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">alleHistorischeVersies</span>, <span style="color: #000000; font-weight: bold;">new</span> Predicate<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> evaluate<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> object<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                BiTemporalObject versie <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>BiTemporalObject<span style="color: #009900;">&#41;</span> object<span style="color: #339933;">;</span>
                <span style="color: #000000; font-weight: bold;">return</span> versie.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>actueleVersie<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> versie.<span style="color: #006633;">isGeldigOp</span><span style="color: #009900;">&#40;</span>registratieTijdstip, peildatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>De wijzigingen ten opzichte van de <code>BiTemporalProperty</code> uit het vorige deel zijn dat er nu niet één maar meer versies tegelijkertijd geldig kunnen zijn (<code>getActueleVersies</code>) en dat we versies kunnen toevoegen (<code>voegActueleVersieToe</code>) en kunnen wijzigen (<code>wijzigActueleVersie</code>). Bij deze laatste methode we de te wijzigen versie meegeven, zodat deze beëindigd kan worden en de nieuwe versie toegevoegd wordt. Ook  kunnen we alle versies van de collection beëindigen (<code>beeindig</code>) of een enkele versie (die dan weer aan de methode meegegeven moet worden).</p>
<h3>Een voorbeeld</h3>
<p>In dit voorbeeld wordt het voorbeeld uit deel 3 uitgebreid met een manager (zelf ook een werknemer), die meerdere werknemers onder zich heeft. </p>
<p><strong>Manager</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Manager <span style="color: #000000; font-weight: bold;">extends</span> Werknemer <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">long</span> serialVersionUID <span style="color: #339933;">=</span> 1L<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> BiTemporalCollection werknemers <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> BiTemporalCollection<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Manager<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Manager<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> naam<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span>naam<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> voegWerknemerToe<span style="color: #009900;">&#40;</span>Werknemer werknemer, <span style="color: #003399;">Date</span> ingangsdatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">werknemers</span>.<span style="color: #006633;">voegActueleVersieToe</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> WerknemerRelatie<span style="color: #009900;">&#40;</span>werknemer, ingangsdatum<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">List</span> getTeManagenWerknemers<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">List</span> relaties <span style="color: #339933;">=</span> getWerknemerRelaties<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        CollectionUtils.<span style="color: #006633;">transform</span><span style="color: #009900;">&#40;</span>relaties, <span style="color: #000000; font-weight: bold;">new</span> Transformer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Object</span> transform<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> object<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>WerknemerRelatie<span style="color: #009900;">&#41;</span>object<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getWerknemer</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">return</span> relaties<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">List</span> getTeManagenWerknemers<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> registratieTijdstip, <span style="color: #003399;">Date</span> peildatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">List</span> relaties <span style="color: #339933;">=</span> getWerknemerRelaties<span style="color: #009900;">&#40;</span>registratieTijdstip, peildatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        CollectionUtils.<span style="color: #006633;">transform</span><span style="color: #009900;">&#40;</span>relaties, <span style="color: #000000; font-weight: bold;">new</span> Transformer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Object</span> transform<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> object<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>WerknemerRelatie<span style="color: #009900;">&#41;</span>object<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getWerknemer</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">return</span> relaties<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">List</span> getWerknemerRelaties<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">werknemers</span>.<span style="color: #006633;">getActueleVersies</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">List</span> getWerknemerRelaties<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> registratieTijdstip, <span style="color: #003399;">Date</span> peildatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">werknemers</span>.<span style="color: #006633;">getVersieOp</span><span style="color: #009900;">&#40;</span>registratieTijdstip, peildatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> wijzigWerknemer<span style="color: #009900;">&#40;</span>Werknemer nieuweWerknemer, Werknemer oudeWerknemer, <span style="color: #003399;">Date</span> wijzigingsdatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        WerknemerRelatie nieuweRelatie <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> WerknemerRelatie<span style="color: #009900;">&#40;</span>nieuweWerknemer, wijzigingsdatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        WerknemerRelatie oudeRelatie <span style="color: #339933;">=</span> bepaalWerknemerRelatie<span style="color: #009900;">&#40;</span>oudeWerknemer<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">werknemers</span>.<span style="color: #006633;">wijzigActueleVersie</span><span style="color: #009900;">&#40;</span>nieuweRelatie, oudeRelatie<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> WerknemerRelatie bepaalWerknemerRelatie<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> Werknemer werknemer<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>WerknemerRelatie<span style="color: #009900;">&#41;</span>CollectionUtils.<span style="color: #006633;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">werknemers</span>.<span style="color: #006633;">getActueleVersies</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #000000; font-weight: bold;">new</span> Predicate<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> evaluate<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> obj<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>WerknemerRelatie<span style="color: #009900;">&#41;</span>obj<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getWerknemer</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>werknemer<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> stopManagenVanWerknemer<span style="color: #009900;">&#40;</span>Werknemer werknemer, <span style="color: #003399;">Date</span> einddatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        WerknemerRelatie relatie <span style="color: #339933;">=</span> bepaalWerknemerRelatie<span style="color: #009900;">&#40;</span>werknemer<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">werknemers</span>.<span style="color: #006633;">beeindig</span><span style="color: #009900;">&#40;</span>relatie, einddatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> stopManagen<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> einddatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">werknemers</span>.<span style="color: #006633;">beeindig</span><span style="color: #009900;">&#40;</span>einddatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Deze klasse representeert de manager. Als een manager een werknemer gaat managen, wordt de werknemer toegevoegd aan de lijst van te managen werknemers (<code>voegWerknemerToe</code>). Als een werknemer wordt vervangen door een andere werknemer wordt de methode <code>wijzigWerknemer</code> aangeroepen, waardoor de relatie met de oude werknemer wordt beëindigd en de nieuwe werknemer wordt begonnen. Als een werknemer uit dienst gaat of naar een andere afdeling, stopt de manager met het managen van deze werknemer (<code>stopManagenVanWerknemer</code>), waardoor de historische relatie van de manager met de werknemer wordt beëindigd. Als de manager stopt met managen (<code>stopManagen</code>), wordt de relatie met alle gemanagede werknemers beëindigd.</p>
<p>De historische relatie van de manager met de werknemer wordt gerepresenteerd door de klasse <code>WerknemerRelatie</code>.</p>
<p><strong>WerknemerRelatie</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> WerknemerRelatie <span style="color: #000000; font-weight: bold;">extends</span> BiTemporalObject <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">long</span> serialVersionUID <span style="color: #339933;">=</span> 1L<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> Werknemer werknemer<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> WerknemerRelatie<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> WerknemerRelatie<span style="color: #009900;">&#40;</span>Werknemer werknemer, <span style="color: #003399;">Date</span> ingangsdatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span>ingangsdatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">werknemer</span><span style="color: #339933;">=</span> werknemer<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Werknemer getWerknemer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">werknemer</span> <span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>De test ziet er als volgt uit:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> testManager<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	Manager jan <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Manager<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Jan&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// simuleer de opvoer tijd 1-1-2003</span>
	<span style="color: #003399;">Date</span> aanvangsdatum <span style="color: #339933;">=</span> DateUtils.<span style="color: #006633;">maakDate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2003</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	BiTemporalObject.<span style="color: #006633;">TEST_OPVOER_TIJDSTIP</span> <span style="color: #339933;">=</span> aanvangsdatum<span style="color: #339933;">;</span> 
&nbsp;
	Afdeling inkoop <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Afdeling<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Inkoop&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	jan.<span style="color: #006633;">setAfdeling</span><span style="color: #009900;">&#40;</span>inkoop, aanvangsdatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	Werknemer kees <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Werknemer<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Kees&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	kees.<span style="color: #006633;">setAfdeling</span><span style="color: #009900;">&#40;</span>inkoop, aanvangsdatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	jan.<span style="color: #006633;">voegWerknemerToe</span><span style="color: #009900;">&#40;</span>kees, aanvangsdatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	Werknemer piet <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Werknemer<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Piet&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	piet.<span style="color: #006633;">setAfdeling</span><span style="color: #009900;">&#40;</span>inkoop, aanvangsdatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	jan.<span style="color: #006633;">voegWerknemerToe</span><span style="color: #009900;">&#40;</span>piet, aanvangsdatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	assertEquals<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span>, jan.<span style="color: #006633;">getTeManagenWerknemers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	assertTrue<span style="color: #009900;">&#40;</span>jan.<span style="color: #006633;">getTeManagenWerknemers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">contains</span><span style="color: #009900;">&#40;</span>kees<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	assertTrue<span style="color: #009900;">&#40;</span>jan.<span style="color: #006633;">getTeManagenWerknemers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">contains</span><span style="color: #009900;">&#40;</span>piet<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #003399;">Date</span> wijzigingsdatum <span style="color: #339933;">=</span> DateUtils.<span style="color: #006633;">maakDate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2006</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	BiTemporalObject.<span style="color: #006633;">TEST_OPVOER_TIJDSTIP</span> <span style="color: #339933;">=</span> wijzigingsdatum<span style="color: #339933;">;</span> 
&nbsp;
	Werknemer johan <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Werknemer<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Johan&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	johan.<span style="color: #006633;">setAfdeling</span><span style="color: #009900;">&#40;</span>inkoop, wijzigingsdatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Johan vervangt Piet, die uit dienst gaat</span>
	jan.<span style="color: #006633;">wijzigWerknemer</span><span style="color: #009900;">&#40;</span>johan, piet, wijzigingsdatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	piet.<span style="color: #006633;">uitDienst</span><span style="color: #009900;">&#40;</span>wijzigingsdatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	assertEquals<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span>, jan.<span style="color: #006633;">getTeManagenWerknemers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	assertTrue<span style="color: #009900;">&#40;</span>jan.<span style="color: #006633;">getTeManagenWerknemers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">contains</span><span style="color: #009900;">&#40;</span>johan<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	assertFalse<span style="color: #009900;">&#40;</span>jan.<span style="color: #006633;">getTeManagenWerknemers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">contains</span><span style="color: #009900;">&#40;</span>piet<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// jan managete gisteren piet nog wel</span>
	<span style="color: #003399;">Date</span> gisteren <span style="color: #339933;">=</span> DateUtils.<span style="color: #006633;">maakDate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2005</span>, <span style="color: #cc66cc;">12</span>, <span style="color: #cc66cc;">31</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	assertTrue<span style="color: #009900;">&#40;</span>jan.<span style="color: #006633;">getTeManagenWerknemers</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, gisteren<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">contains</span><span style="color: #009900;">&#40;</span>piet<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #003399;">Date</span> einddatum <span style="color: #339933;">=</span> DateUtils.<span style="color: #006633;">maakDate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2009</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	BiTemporalObject.<span style="color: #006633;">TEST_OPVOER_TIJDSTIP</span> <span style="color: #339933;">=</span> wijzigingsdatum<span style="color: #339933;">;</span> 
&nbsp;
	jan.<span style="color: #006633;">stopManagenVanWerknemer</span><span style="color: #009900;">&#40;</span>kees, einddatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	kees.<span style="color: #006633;">uitDienst</span><span style="color: #009900;">&#40;</span>einddatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	assertEquals<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>, jan.<span style="color: #006633;">getTeManagenWerknemers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	assertFalse<span style="color: #009900;">&#40;</span>jan.<span style="color: #006633;">getTeManagenWerknemers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">contains</span><span style="color: #009900;">&#40;</span>kees<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	jan.<span style="color: #006633;">stopManagen</span><span style="color: #009900;">&#40;</span>einddatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	assertTrue<span style="color: #009900;">&#40;</span>jan.<span style="color: #006633;">getTeManagenWerknemers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">isEmpty</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>In deze test maken we een manager Jan aan, die werkt op de afdeling Inkoop op 1 januari 2003. Vanaf deze dag begint hij ook met het managen van twee werknemers Kees en Piet. Vanaf 1 januari 2006 vervangt een nieuwe werknemer Johan Piet, die uit dienst gaat. Op 1 januari 2009 stopt Jan met het managen van al zijn werknemers.</p>
<h3>Hibernate mappings</h3>
<p>De hibernate mapping van de klasse <code>WerknemerRelatie<code> is analoog aan de mapping van de <code>AfdelingRelatie</code> uit deel 3. </p>
<p>De mapping van de werknemer is uitgebreid met de subclass Manager, die de werknemers als BiTemporalCollection property mapt. </p>
<p><strong>Werknemer.hbm.xml</strong></p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;hibernate-mapping</span> <span style="color: #000066;">package</span>=<span style="color: #ff0000;">&quot;nl.ordina.bitemporal.example&quot;</span> <span style="color: #000066;">default-access</span>=<span style="color: #ff0000;">&quot;field&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;class</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;Werknemer&quot;</span> <span style="color: #000066;">table</span>=<span style="color: #ff0000;">&quot;Werknemer&quot;</span> <span style="color: #000066;">discriminator-value</span>=<span style="color: #ff0000;">&quot;Werknemer&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;id</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;id&quot;</span> <span style="color: #000066;">column</span>=<span style="color: #ff0000;">&quot;id&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;generator</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;identity&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/generator<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;discriminator</span> <span style="color: #000066;">column</span>=<span style="color: #ff0000;">&quot;type&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;version</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;versie&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
		<span style="color: #808080; font-style: italic;">&lt;!-- properties --&gt;</span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;naam&quot;</span> <span style="color: #000066;">column</span>=<span style="color: #ff0000;">&quot;naam&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
		<span style="color: #808080; font-style: italic;">&lt;!-- de verwijzing naar de afdelingrelatie --&gt;</span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;component</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;afdelingRelatie&quot;</span> </span>
<span style="color: #009900;">			<span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;nl.ordina.temporal.bitemporal.BiTemporalProperty&quot;</span></span>
<span style="color: #009900;">			<span style="color: #000066;">lazy</span>=<span style="color: #ff0000;">&quot;false&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;bag</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;alleHistorischeVersies&quot;</span></span>
<span style="color: #009900;">				<span style="color: #000066;">cascade</span>=<span style="color: #ff0000;">&quot;all, delete-orphan&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span></span>
				<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key</span> <span style="color: #000066;">column</span>=<span style="color: #ff0000;">&quot;werknemerId&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
				<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;one-to-many</span></span>
<span style="color: #009900;">					<span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;AfdelingRelatie&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/bag<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/component<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;subclass</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;Manager&quot;</span> <span style="color: #000066;">discriminator-value</span>=<span style="color: #ff0000;">&quot;Manager&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
		<span style="color: #808080; font-style: italic;">&lt;!-- de verwijzing naar de werknemerrelatie --&gt;</span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;component</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;werknemers&quot;</span> </span>
<span style="color: #009900;">				<span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;nl.ordina.temporal.bitemporal.BiTemporalCollection&quot;</span></span>
<span style="color: #009900;">				<span style="color: #000066;">lazy</span>=<span style="color: #ff0000;">&quot;false&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
				<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;bag</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;alleHistorischeVersies&quot;</span></span>
<span style="color: #009900;">					<span style="color: #000066;">cascade</span>=<span style="color: #ff0000;">&quot;all, delete-orphan&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span></span>
					<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key</span> <span style="color: #000066;">column</span>=<span style="color: #ff0000;">&quot;managerId&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
					<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;one-to-many</span></span>
<span style="color: #009900;">						<span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;WerknemerRelatie&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
				<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/bag<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/component<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/subclass<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/hibernate-mapping<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p><strong>LET OP</strong>: In bovenstaand artikel wordt gesproken over <code>BiTemporalCollection</code>. Dit is niet dezelfde als de <a href="http://martinfowler.com/ap2/temporalProperty.html">BiTemporalCollection van Fowler</a> , wat eigenlijk de <code>BiTemporalProperty</code> uit deel 3 is.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smart-java.nl/blog/index.php/2009/12/07/temporale-data-%e2%80%93-deel-4-bitemporale-collections/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What is OSGi? (short version)</title>
		<link>http://blog.smart-java.nl/blog/index.php/2009/05/29/what-is-osgi-short-version/</link>
		<comments>http://blog.smart-java.nl/blog/index.php/2009/05/29/what-is-osgi-short-version/#comments</comments>
		<pubDate>Fri, 29 May 2009 07:36:15 +0000</pubDate>
		<dc:creator>Stephan Oudmaijer</dc:creator>
				<category><![CDATA[Java language]]></category>

		<guid isPermaLink="false">http://blog.smart-java.nl/blog/?p=394</guid>
		<description><![CDATA[Since modularisation is a hot topic for Java 7, most developers by now should have a basic understanding about what OSGi is. But I often get the question; What is OSGi?
OSGi is The Dynamic Module System for Java[TM]. OSGi enables Java applications to become modulair and express dependencies on (versions of) other modules. Which means [...]]]></description>
			<content:encoded><![CDATA[<p>Since modularisation is a hot topic for Java 7, most developers by now should have a basic understanding about what OSGi is. But I often get the question; What is OSGi?</p>
<p>OSGi is The Dynamic Module System for Java[TM]. OSGi enables Java applications to become modulair and express dependencies on (versions of) other modules. Which means that your application no longer depend on the classloader (not) taking care of dependencies. There are a number of issues OSGi addresses, but I wont even bother writing them down here since Peter Kriens has an excellent blog post about <a href="http://www.osgi.org/blog/2008_12_01_archive.html">those issues</a>.</p>
<p>Java 7, and in particular JSR294, also tries to solve the modularisation problem. The expert group is working with the OSGi alliance to implement modularisation in Java, but they still have a long way to go. If you are interested in the progress of the expert group you can follow the <a href="http://altair.cs.oswego.edu/pipermail/jsr294-modularity-eg/">JSR294 EG mailing list</a>.</p>
<p>Below is a list of resources about OSGi:</p>
<ul>
<li>http://www.infoq.com/presentations/osgi-the-foundation</li>
<li>http://www.infoq.com/presentations/colyer-server-side-osgi</li>
<li>http://www.infoq.com/presentations/dm-Server-Rod-Johnson</li>
<li>http://www.osgi.org/blog/2008_12_01_archive.html</li>
<li>http://www.theserverside.com/tt/articles/article.tss?l=MigratingPathToOSGi</li>
</ul>
<p>Now you know!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smart-java.nl/blog/index.php/2009/05/29/what-is-osgi-short-version/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Compare with generics please..!</title>
		<link>http://blog.smart-java.nl/blog/index.php/2009/05/18/compare-with-generics-please/</link>
		<comments>http://blog.smart-java.nl/blog/index.php/2009/05/18/compare-with-generics-please/#comments</comments>
		<pubDate>Mon, 18 May 2009 12:12:31 +0000</pubDate>
		<dc:creator>Roy van Rijn</dc:creator>
				<category><![CDATA[Java language]]></category>
		<category><![CDATA[generics]]></category>
		<category><![CDATA[java 5]]></category>

		<guid isPermaLink="false">http://blog.smart-java.nl/blog/?p=385</guid>
		<description><![CDATA[I&#8217;ve been developing with Java 5+ for quite a while now. Not all developers are this lucky, some are still stuck with 1.4&#8230; some even with 1.3! But my clients all made the excellent step forward to Java 5 (some even to 6). The problem is, they moved the runtime/JDK but most clients forget to move their developers!
The language brings some [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been developing with Java 5+ for quite a while now. Not all developers are this lucky, some are still stuck with 1.4&#8230; some even with 1.3! But my clients all made the excellent step forward to Java 5 (some even to 6). The problem is, they moved the runtime/JDK but most clients forget to move their developers!</p>
<p>The language brings some good improvements, the for-loop is easy to understand, and almost all the developers are using this by now. The problem starts with generics. There is a part most developers understand, the Collections API. Almost all programmers use lists now as: List&lt;Integer&gt; instead of a plain old List. This is a good start, but it must not end here! First, I must admit, generics in Java can sometimes be hard and confusing (when using &lt;? extends X&gt; and &lt;? super X&gt;). So I&#8217;m not talking about the hard stuff. Its the use of &#8216;easy&#8217; generics that can be extended to make life so much easier.</p>
<p>For example the piece of code below:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> LabelPlaceholderComparator <span style="color: #000000; font-weight: bold;">implements</span> <span style="color: #003399;">Comparator</span> <span style="color: #009900;">&#123;</span> 
&nbsp;
    <span style="color: #008000; font-style: italic; font-weight: bold;">/**{@inheritDoc */</span> 
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">int</span> compare<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> o1, <span style="color: #003399;">Object</span> o2<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
        LabelPlaceholder p1 <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>LabelPlaceholder<span style="color: #009900;">&#41;</span> o1<span style="color: #339933;">;</span> 
        LabelPlaceholder p2 <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>LabelPlaceholder<span style="color: #009900;">&#41;</span> o2<span style="color: #339933;">;</span> 
        <span style="color: #000000; font-weight: bold;">return</span> p1.<span style="color: #006633;">getLabel</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">compareTo</span><span style="color: #009900;">&#40;</span>p2.<span style="color: #006633;">getLabel</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Of course, there seems to be not much wrong with the code, I see it all the time. Yes, the code breaks if you put something else in the comparator, but hey&#8230; the Javadoc says it only accepts LabelPlaceholders! So lets use this code:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">List<span style="color: #339933;">&lt;</span>LabelPlaceholder<span style="color: #339933;">&gt;</span> holders <span style="color: #339933;">=</span> fillList<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003399;">Collections</span>.<span style="color: #006633;">sort</span><span style="color: #009900;">&#40;</span>holders, <span style="color: #000000; font-weight: bold;">new</span> LabelPlaceholderComparator<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Done! Its working and no problems right? Wrong. The IDE complains about this code. For example Eclipse shouts:<br />
 <br />
<em>Type safety: The expression of type LabelPlaceholderComparator needs unchecked conversion to conform to Comparator&lt;? super T&gt;</em></p>
<p>At this point, most programmers at the company I work for now will just ignore this warning. They might even add:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@SuppressWarnings<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;unchecked&quot;</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>What a shame&#8230; First of all, what is Eclipse trying to tell us here? The compiler doesn&#8217;t know we created the Comparator with only LabelPlaceholders in mind. But the compiler does know (with generics) that the List only contains LabelPlaceholders. So the warning is (in understandable English):</p>
<p><em>I&#8217;ve got a list here of T (LabelPlaceholders) and a Comparator for Objects, this can go wrong! I&#8217;d rather have a specific Comparator for this job. Do you have one for me?</em></p>
<p>The solution to this problem is very simple, but most neglect to use it:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> LabelPlaceholderComparator <span style="color: #000000; font-weight: bold;">implements</span> Comparator<span style="color: #339933;">&lt;</span>LabelPlaceholder<span style="color: #339933;">&gt;</span> <span style="color: #009900;">&#123;</span> 
&nbsp;
    <span style="color: #008000; font-style: italic; font-weight: bold;">/**{@inheritDoc */</span> 
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">int</span> compare<span style="color: #009900;">&#40;</span>LabelPlaceholder p1, LabelPlaceholder p2<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
        <span style="color: #000000; font-weight: bold;">return</span> p1.<span style="color: #006633;">getLabel</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">compareTo</span><span style="color: #009900;">&#40;</span>p2.<span style="color: #006633;">getLabel</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>As you can see, the code is much smaller. The interface is now generified, it knows we are going to compare LabelPlaceholders now, nothing more, nothing less. Also, we don&#8217;t have to cast anymore, because of the generics you can&#8217;t put anything else in there.</p>
<p>So, lets go to the conclusion: Why is the latter code better code?</p>
<ol>
<li>As you can see, the code is smaller!</li>
<li>There are no casts, the code is safer (no ClassCastException or eleborate class checks)</li>
<li>If somebody uses your code, he/she knows what kind of objects the Comparator can handle. You don&#8217;t have to read the Javadoc or the code to see what it does.</li>
</ol>
<p>Throughout the projects I encounter I keep finding examples of places where generics would have made the code smaller/safer/more understandable. For some reason the programmers still only use generics on collections. So, even though generics aren&#8217;t perfect, please use them where/when you can, it&#8217;ll always add clarity to the code, and most of the time it&#8217;ll also make your code safer, and in some cases the code gets smaller because you can leave away casts and class-checks.</p>
<p>Don&#8217;t ever let me see public int compare(Object o1, Object o2); again! <img src='http://blog.smart-java.nl/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smart-java.nl/blog/index.php/2009/05/18/compare-with-generics-please/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Boekbespreking: Programming in Scala</title>
		<link>http://blog.smart-java.nl/blog/index.php/2009/04/12/boekbespreking-programming-in-scala/</link>
		<comments>http://blog.smart-java.nl/blog/index.php/2009/04/12/boekbespreking-programming-in-scala/#comments</comments>
		<pubDate>Sun, 12 Apr 2009 11:30:59 +0000</pubDate>
		<dc:creator>Hedzer Westra</dc:creator>
				<category><![CDATA[Algemeen]]></category>
		<category><![CDATA[Boeken]]></category>
		<category><![CDATA[Java language]]></category>
		<category><![CDATA[Scala]]></category>

		<guid isPermaLink="false">http://blog.smart-java.nl/blog/?p=346</guid>
		<description><![CDATA[
Auteurs: Odersky, Spoon &#38; Venners, publicatiejaar: 2008 (1e druk november, 2e druk binnenkort), uitgever: Artima, pagina’s: 736, ISBN-13: 978-0-9815316-0-1, website: http://www.artima.com/shop/programming_in_scala, prijzen: Jolt Productivity Award 2009 for Technical Books.
Belofte maakt schuld: het is tijd voor mijn eerder aangekondigde boekbespreking van “Programming in Scala”.
Ik vond het een prettig &#38; helder boek. In 33 goed leesbare en [...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-medium wp-image-347" title="pinscover500x500" src="http://blog.smart-java.nl/blog/wp-content/uploads/2009/04/pinscover500x500.gif" alt="Programming in Scala" width="150" height="150" /></p>
<p>Auteurs: Odersky, Spoon &amp; Venners, publicatiejaar: 2008 (1e druk november, 2e druk binnenkort), uitgever: Artima, pagina’s: 736, ISBN-13: 978-0-9815316-0-1, website: <a title="http://www.artima.com/shop/programming_in_scala" href="http://www.artima.com/shop/programming_in_scala">http://www.artima.com/shop/programming_in_scala</a>, prijzen: Jolt Productivity Award 2009 for Technical Books.</p>
<p>Belofte maakt schuld: het is tijd voor mijn eerder aangekondigde boekbespreking van “Programming in Scala”.</p>
<p>Ik vond het een prettig &amp; helder boek. In 33 goed leesbare en goed geordende hoofdstukken worden (bijna) alle onderdelen van de taal en de bijbehorende bibliotheek beschreven.</p>
<p>De hoofdstukken zijn goed gebalanceerd &#8211; niet te lang en niet te kort, niet te simpel en niet te ingewikkeld. “Programming in Scala” is helder van structuur, bevat een uitgebreide woordenlijst en slechts een korte bibliografie.</p>
<p>De auteurs hebben het niet gedaan, maar je kunt wat mij betreft de hoofdstukken ruwweg in 6 delen onderverdelen: inleiding, basis, standaardelementen, gevorderd, extra’s en frameworks.</p>
<p>De tekst bevat veel vooruitverwijzingen en voetnoten. Het onderwerp van veel hoofdstukken wordt een aantal hoofdstukken later weer opgepakt, zodat dat onderwerp even wat tijd heeft gehad om te bezinken. De ‘fast tracks’ maken het mogelijk om lastiger of verdiepende stukken over te slaan.</p>
<p>Naast uitleg over wat Scala is, wordt ook veel duidelijk gemaakt over wat je er mee kunt doen; het verschil in programmeerstijl tussen Imperatief Programmeren (IP) en Functioneel Programmeren (FP) wordt diverse keren behandeld – er is veel voorbeeldcode die laat zien hoe je recursief, en in ’t algemeen in FP-stijl, kunt programmeren. Ook conventies die in de community ontwikkeld zijn, komen aan bod.</p>
<p>Het boek is tevens beschikbaar als eBook – ik had vanaf afgelopen september een preprint tot mijn beschikking. Ik was verbaasd over de leesbaarheid ervan – zelfs op een gewone laptop; niets eens op een speciale eBook reader. Ook is alle voorbeeldcode te downloaden.</p>
<p>Er wordt vrij weinig gerefereerd naar andere talen dan Java. Sowieso vind ik het boek goed leesbaar voor Javanen, maar of dit ook geldt als je kennis meer ligt bij andere talen, vraag ik me af.</p>
<p>Als tipje van de sluier wat betreft de inhoud volgt hier een (korte?) opsomming van de taalaspecten die behandeld worden: traits, closures, case classes, type parameters inclusief variance &amp; erasure, implicits, pattern matching &amp; extractors, for expressions, operator overloading, interne &amp; externe DSL’s, lazy evaluation, currying, 1ste-klasse &amp; hogere-orde functies, typehiërarchie en bibliotheken (onder anderen collecties, XML, Actors, parser combinator, Swing, testen).</p>
<p>Hoofdstuk 28 vond ik een vreemde: hierin wordt namelijk stap voor stap uitgelegd hoe je netjes equals() &amp; hashCode() kunt implementeren. Inderdaad belangrijk, maar helemaal niet Scala-specifiek. Er wordt dan ook veelvuldig wordt gerefereerd naar Joshua Bloch’s “Effective Java.”</p>
<p>Het hoofdstuk over integratie tussen Scala &amp; Java viel me wat tegen – het is erg kort. Nu is het wel zo dat Scala &amp; Java naadloos integreren, en er dus niet al te veel aandacht aan besteed hoeft te worden, maar iets meer had geen kwaad gekund.</p>
<p>Het afsluitende voorbeeld vond ik wel erg interessant. In minder dan 200 regels code worden erg veel taalaspecten gebruikt, en de volgende technieken worden gecombineerd tot een spreadsheetapplicatie: Interne &amp; externe DSL (Swing &amp; formules), termevaluatie en separation of concerns – MVC en Pub/Sub (op 2 niveaus).</p>
<p>“Programming in Scala” is niet bedoeld als referentie of handleiding; dit is duidelijk een leerboek, onder anderen vanwege de grotere &amp; kleinere codevoorbeelden, die de tekst extra verhelderen. Mijn aanbeveling is om ‘t van voor tot achter te lezen, en niet hapsnap, anders zul je details missen. Al met al biedt het boek op een toegankelijke manier een complete behandeling van de taalaspecten van Scala, en kun je – tijdens het lezen al – zelf aan de gang met deze erg interessante taal.</p>
<p>Kleurindicatie: <span style="color: #00ff00;">Groen</span> (3 op schaal van 3)</p>
<p>Nu ik toch jullie aandacht heb wat betreft Scala: op dinsdag 9 juni geef ik een TechSessie over Scala. Primair bedoeld voor J-Tech&#8217;ers, maar natuurlijk zijn alle Ordina-medewerkers welkom. Binnenkort kun je een uitnodiging in de mail verwachten!</p>
<div id="attachment_348" class="wp-caption alignnone" style="width: 103px"><a href="http://blog.smart-java.nl/blog/wp-content/uploads/2009/04/hedzerwestra_93x123.jpg"><img class="size-medium wp-image-348" title="hedzerwestra_93x123" src="http://blog.smart-java.nl/blog/wp-content/uploads/2009/04/hedzerwestra_93x123.jpg" alt="Hedzer Westra" width="93" height="123" /></a><p class="wp-caption-text">Hedzer Westra</p></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.smart-java.nl/blog/index.php/2009/04/12/boekbespreking-programming-in-scala/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JDK 7 language changes: DeVoxx poll</title>
		<link>http://blog.smart-java.nl/blog/index.php/2009/03/08/jdk-7-language-changes-devoxx-poll/</link>
		<comments>http://blog.smart-java.nl/blog/index.php/2009/03/08/jdk-7-language-changes-devoxx-poll/#comments</comments>
		<pubDate>Sun, 08 Mar 2009 16:07:45 +0000</pubDate>
		<dc:creator>Jan-Kees van Andel</dc:creator>
				<category><![CDATA[Java API]]></category>
		<category><![CDATA[Java language]]></category>
		<category><![CDATA[JDK 7]]></category>

		<guid isPermaLink="false">http://blog.smart-java.nl/blog/?p=325</guid>
		<description><![CDATA[Afgelopen DeVoxx is een stemming geweest waar de bezoekers konden stemmen op hun favoriete nieuwe JDK 7 features.
De grote wijzigingen zijn natuurlijk allang bepaald, zoals !closures (niet dus), JVM optimalisaties voor scripttalen (JSR 292) en Java Module System (JSR 294), maar voor JDK 7 willen ze ook een aantal kleinere wijzigingen faciliteren.
Stephen Colebourne heeft op [...]]]></description>
			<content:encoded><![CDATA[<p>Afgelopen DeVoxx is een stemming geweest waar de bezoekers konden stemmen op hun favoriete nieuwe JDK 7 features.<br />
De grote wijzigingen zijn natuurlijk allang bepaald, zoals !closures (niet dus), JVM optimalisaties voor scripttalen (<a href="http://jcp.org/en/jsr/detail?id=292">JSR 292</a>) en Java Module System (<a href="http://jcp.org/en/jsr/detail?id=294">JSR 294</a>), maar voor JDK 7 willen ze ook een aantal kleinere wijzigingen faciliteren.<br />
Stephen Colebourne heeft op zijn blog een mooie <a href="http://www.jroller.com/scolebourne/entry/jdk_7_language_changes_devoxx">samenvatting</a> van de poll geplaatst.<br />
Zoals je kunt zien, zitten er 3 populaire tussen:</p>
<ol>
<li>Null handling</li>
<li>Infer generics</li>
<li>Multi catch</li>
</ol>
<p>Properties is ook populair, maar deze komt sowieso niet in JDK 7.<br />
Deze 3 populaire features zal ik even kort laten zien:</p>
<p><b>Null handling</b><br />
Iedereen heeft weleens dergelijke code gezien:</p>

<div class="wp_syntax"><div class="code"><pre class="java5" style="font-family:monospace;"><span style="color: #000000;  font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>myObject <span style="color: #339933;">!</span>= <span style="color: #006600; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000;  font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>myObject.<span style="color: #006633;">getProp</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!</span>= <span style="color: #006600; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000;  font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>myObject.<span style="color: #006633;">getProp</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getProp</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!</span>= <span style="color: #006600; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">return</span> myObject.<span style="color: #006633;">getProp</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getProp</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Zou het niet relaxed zijn als je het zo kunt schrijven?</p>

<div class="wp_syntax"><div class="code"><pre class="java5" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">return</span> myObject<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">?</span>.<span style="color: #006633;">getProp</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">?</span>.<span style="color: #006633;">getProp</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">?</span>.<span style="color: #006633;">getString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Er zitten nog wat vergelijkbare constructies aan vast, zoals een aanpassing aan de ternary operator, zie <a href="http://tech.puredanger.com/java7/#null">Alex Millers blog</a>.</p>
<p><b>Infer generics</b><br />
Waarschijnlijk hebben jullie deze constructie ook weleens gezien? Zo nee, dan heb je waarschijnlijk nog geen JDK 5+ collections gebruikt. <img src='http://blog.smart-java.nl/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<div class="wp_syntax"><div class="code"><pre class="java5" style="font-family:monospace;">List<span style="color: #339933;">&lt;</span>String<span style="color: #339933;">&gt;</span> list = <span style="color: #000000; font-weight: bold;">new</span> ArrayList<span style="color: #339933;">&lt;</span>String<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Dit is nog niet zo vervelend, maar wat dacht je van deze variant?</p>

<div class="wp_syntax"><div class="code"><pre class="java5" style="font-family:monospace;">Map<span style="color: #339933;">&lt;</span>String, AtomicReference<span style="color: #339933;">&lt;</span>SoftReference<span style="color: #339933;">&lt;</span>SomeObject<span style="color: #339933;">&gt;&gt;&gt;</span> list = <span style="color: #000000; font-weight: bold;">new</span> ConcurrentHashMap<span style="color: #339933;">&lt;</span>String, AtomicReference<span style="color: #339933;">&lt;</span>SoftReference<span style="color: #339933;">&lt;</span>SomeObject<span style="color: #339933;">&gt;&gt;&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Vrij lelijk als je het aan mij vraagt. En in de meeste gevallen is het niet eens nuttig, aangezien links en rechts van de assignment hetzelfde staat.<br />
Wat dacht je hiervan?</p>

<div class="wp_syntax"><div class="code"><pre class="java5" style="font-family:monospace;">Map<span style="color: #339933;">&lt;</span>AtomicReference<span style="color: #339933;">&lt;</span>SoftReference<span style="color: #339933;">&lt;</span>SomeObject<span style="color: #339933;">&gt;&gt;&gt;</span> list = <span style="color: #000000; font-weight: bold;">new</span> ConcurrentHashMap<span style="color: #339933;">&lt;&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>De haken aan de rechterkant geven aan dat de compiler de typespecificatie links van de assignment naar de rechterkant gekopieerd moet worden.<br />
Zie wederom <a href="http://tech.puredanger.com/java7/#typeinference">Alex Millers blog</a> voor de details.</p>
<p><b>Ten slotte de Multi catch</b><br />
Jullie hebben ook vast weleens dergelijke catch clausules gehad neem ik aan.</p>

<div class="wp_syntax"><div class="code"><pre class="java5" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Do something</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span>Exception1 e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    LOG.<span style="color: #006633;">error</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Something horrible happened&quot;</span>, e<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span>Exception2 e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    LOG.<span style="color: #006633;">error</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Something horrible happened&quot;</span>, e<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span>Exception3 e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    LOG.<span style="color: #006633;">error</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Something horrible happened&quot;</span>, e<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span>Exception4 e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    LOG.<span style="color: #006633;">error</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Something horrible happened&quot;</span>, e<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>&#8220;catch (Exception)&#8221; is niet netjes, hebben we allemaal geleerd. Voor je het weet, vang je onterecht een fout af. Maar al die code duplicatie zit je toch niet lekker. Vandaar een nieuw alternatief:</p>

<div class="wp_syntax"><div class="code"><pre class="java5" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Do something</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span>Exception1 | Exception2 | Exception3 | Exception4 e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    LOG.<span style="color: #006633;">error</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Something horrible happened&quot;</span>, e<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Dat is een stuk beter he? Vooral in combinatie met Safe Rethrow kan dit erg krachtig zijn.<br />
Ik ben nog wel benieuwd naar de details, want wat is het type van &#8220;e&#8221;? Gaan ze op zoek naar een common supertype, of wordt het <a href="http://en.wikipedia.org/wiki/Duck_typing">duck typing</a>?<br />
En weer een linkje naar <a href="http://tech.puredanger.com/java7/#catch">Alex Miller</a>.</p>
<p><b>Dusss&#8230;</b><br />
Dit zijn maar een paar van de toevoegingen waar momenteel aan gewerkt wordt. Meer info over <a href="http://blogs.sun.com/darcy/entry/project_coin">&#8220;Project Coin&#8221; op Joe Darcy&#8217;s blog</a>.<br />
En natuurlijk weer <a href="http://tech.puredanger.com/java7/">Alex Miller</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smart-java.nl/blog/index.php/2009/03/08/jdk-7-language-changes-devoxx-poll/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Scala: too hot to handle?</title>
		<link>http://blog.smart-java.nl/blog/index.php/2009/01/29/scala-too-hot-to-handle/</link>
		<comments>http://blog.smart-java.nl/blog/index.php/2009/01/29/scala-too-hot-to-handle/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 18:30:48 +0000</pubDate>
		<dc:creator>Hedzer Westra</dc:creator>
				<category><![CDATA[Architectuur]]></category>
		<category><![CDATA[Java language]]></category>
		<category><![CDATA[Clojure]]></category>
		<category><![CDATA[Scala]]></category>

		<guid isPermaLink="false">http://blog.smart-java.nl/blog/?p=288</guid>
		<description><![CDATA[Het blog item van 21 januari sloot ik af met: &#8220;Ikzelf hoop binnenkort te komen met een bespreking van &#8216;Programming in Scala,&#8217; het eerste boek over deze nieuwe en spannende programmeertaal.&#8221;
Prompt reageerde Jan-Kees van Andel: &#8220;Ik verwacht niet dat Scala verder zal groeien qua populariteit. Op de JVM Language Summit 2008 was de algemene opinie [...]]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal">Het blog item van 21 januari sloot ik af met: &#8220;Ikzelf hoop binnenkort te komen met een bespreking van &#8216;Programming in Scala,&#8217; het eerste boek over deze nieuwe en spannende programmeertaal.&#8221;</p>
<p class="MsoNormal">Prompt reageerde Jan-Kees van Andel: &#8220;Ik verwacht niet dat Scala verder zal groeien qua populariteit. Op de JVM Language Summit 2008 was de algemene opinie dat Scala het niet gaat worden omdat het te moeilijk is. En dat &#8216;te moeilijk&#8217; komt uit de mond van hele capabele mensen (lees: JVM taalontwerpers). Zij waren vooral gecharmeerd van Clojure.&#8221;</p>
<p class="MsoNormal">Aangezien ik me ten doel heb gesteld om Scala dit jaar onder de aandacht te brengen bij mijn J-Tech collega&#8217;s, kan ik dat natuurlijk niet over mijn kant laten gaan <img src='http://blog.smart-java.nl/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p class="MsoNormal">Als je het hebt over JVM taalontwerpers: de auteur van Scala, Martin Odersky, is bedenker van Java generics, en ontwikkelaar van de Java 1.2 reference compiler. Zelf maakt hij dus ook deel uit van deze groep, en hijzelf is nog allerminst klaar met Scala.</p>
<p class="MsoNormal">Onlangs is bekend geworden dat Java7 geen closures zal krijgen &#8211; men kon geen beslissing nemen. Eind augustus/begin september postte Jan-Kees nog hoopvol een artikel waarin de drie onderhanden voorstellen behandeld werden, maar helaas zal geen ervan het licht gaan zien in Java7. Dat op zich is al een goed argument om naar Scala te kijken: daar zitten closures rotsvast in de basis van de taal.</p>
<p class="MsoNormal">Natuurlijk heeft Clojure ook closures (vandaar de naam&#8230;), maar als je kijkt naar de syntax van Clojure, zie je meteen waar deze voornamelijk op gebaseerd is: LISP. En dat staat niet voor niets voor Lots of Irritating Silly Parentheses (eigenlijk LISt Processing, maar je snapt waar ik heen wil). LISP stamt uit de jaren &#8216;50/&#8217;60 van het vorige millennium en heeft begrijpelijkerwijs een inmiddels verouderde syntax. De Scala syntax daarentegen is grotendeels op Java gebaseerd, wat de overstap Java -&gt; Scala mijns inziens eenvoudiger maakt.</p>
<p class="MsoNormal">Een ander punt is dat ik een beetje gelogen heb toen ik zei &#8220;deze nieuwe [..] programmeertaal&#8221;: Scala is al sinds 2001 in ontwikkeling, en niet door de minste wetenschappers, en is zodoende al vergaand uitontwikkeld. Clojure begon pas in 2005.</p>
<p class="MsoNormal">Scala&#8217;s propositie is dat het een schaalbare taal is (&#8216;SCAlable LAnguage&#8217;). Niet alleen in de zin van performance bij gebruik op multi-core systemen, maar ook &#8211; en veel belangrijker &#8211; schaalbaar naar het type applicatie dat je er mee wilt bouwen. Dat varieert van script via desktop applicatie tot enterprise systeem. De syntax ondersteunt al deze applicaties op dezelfde manier. Dat gezegd hebbende, is Scala een rijke taal, die je &#8211; naar wens &#8211; kunt gebruiken als &#8216;Java on steroids&#8217;, dan wel als een bijna-pure functionele taal à la Haskell. Als je dat laatste wilt, en momenteel alleen Java beheerst, is dat inderdaad nogal een klus, en kan ik me voorstellen dat je de taal als &#8216;te moeilijk&#8217; bestempelt. Maar als je kiest voor het eerste, en je je de taal langzamerhand eigen maakt, kunt je zogezegd &#8216;opschalen&#8217; naar een meer functioneel gerichte programmeerstijl. Kan allemaal in Scala.</p>
<p class="MsoNormal">Wat betreft de functionele programmeerstijl (FP): die is echt fundamenteel anders dan de imperatieve OO programmeerstijl die voor bijvoorbeeld Java de voorkeur geniet. Dat moet je dus leren, en leren is altijd (in meer of mindere mate) moeilijk &#8211; maar om daar meteen de taal de schuld van te geven? Als je overstapt van C naar Java moet je ook een nieuwe, in het begin moeilijke, stijl aanleren, maar uiteindelijk is dat de moeite dubbel en dwars waard. Voor FP geldt dat evenzogoed. Als je echt &#8216;hardcore&#8217; puur FP wilt proeven, zou je eens kunnen kijken naar Haskell of ML. Maar dat is niet voor niets, ondanks jaren taalontwikkeling, nog steeds het domein van wiskundig opgeleide academici &#8211; programmeren in die talen wordt snel heel erg abstract (hoor ik iemand &#8216;Monads!&#8217; roepen?). Scala is veel meer &#8216;down to earth&#8217; en bereikbaar voor de gewone stervelingen.</p>
<p class="MsoNormal">Mocht je nog niet overtuigd zijn dat <a title="Scala" href="http://www.scala-lang.org/">Scala</a> toch echt wel wat meer aandacht verdient, check dan de <a title="Wiki" href="https://wiki.ordina.nl/confluence/display/JAVA/Scala">Wiki</a> die ik ingericht heb (helaas alleen voor Ordinamedewerkers). Daarop vind je een powerpoint van een presentatie die ik onlangs gaf bij een architectuur intervisie meeting, een draft cookbook en een Eclipse workspace met veel kleine codevoorbeeldjes. Wel eerst even de <a title="Scala plugin" href="http://www.scala-lang.org/scala-eclipse-plugin">Scala plugin</a> installeren!</p>
<p class="MsoNormal">Een special meeting Scala zit in de koker. Ook kun je extra blog items van me verwachten over bijvoorbeeld Liftweb en Sweet, twee web frameworks in Scala. A propos: ik ben nog op zoek naar reviewers voor mijn kookboek! Wie meldt zich aan als proeflezer?</p>
<div id="attachment_289" class="wp-caption alignnone" style="width: 103px"><a href="http://blog.smart-java.nl/blog/wp-content/uploads/2009/01/hedzerwestra_93x1231.jpg"><img class="size-medium wp-image-289" title="hedzerwestra_93x1231" src="http://blog.smart-java.nl/blog/wp-content/uploads/2009/01/hedzerwestra_93x1231.jpg" alt="Hedzer Westra" width="93" height="123" /></a><p class="wp-caption-text">Hedzer Westra</p></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.smart-java.nl/blog/index.php/2009/01/29/scala-too-hot-to-handle/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[Closures] Introductie</title>
		<link>http://blog.smart-java.nl/blog/index.php/2008/08/29/closures-introductie/</link>
		<comments>http://blog.smart-java.nl/blog/index.php/2008/08/29/closures-introductie/#comments</comments>
		<pubDate>Fri, 29 Aug 2008 08:35:26 +0000</pubDate>
		<dc:creator>Jan-Kees van Andel</dc:creator>
				<category><![CDATA[Java API]]></category>
		<category><![CDATA[Java language]]></category>
		<category><![CDATA[BGGA]]></category>
		<category><![CDATA[CICE + ARM]]></category>
		<category><![CDATA[Closures]]></category>
		<category><![CDATA[FCM+JCA]]></category>
		<category><![CDATA[Java 7]]></category>

		<guid isPermaLink="false">http://blog.smart-java.nl/blog/?p=136</guid>
		<description><![CDATA[Closures, één van de meest bediscussieerde onderwerpen van de afgelopen paar jaren in de Java wereld. Deels een hype, deels bieden closures meerwaarde voor Java development. Ik ga niet meedoen met alle discussies waarom ze (niet) gewenst zijn, maar het is een feit dat het mogelijkheden biedt qua API design. In dit stuk hoop ik [...]]]></description>
			<content:encoded><![CDATA[<p>Closures, één van de meest bediscussieerde onderwerpen van de afgelopen paar jaren in de Java wereld. Deels een hype, deels bieden closures meerwaarde voor Java development. Ik ga niet meedoen met alle discussies waarom ze (niet) gewenst zijn, maar het is een feit dat het mogelijkheden biedt qua API design. In dit stuk hoop ik a) de mystieken van closures iets duidelijker te maken en b) wat inzicht te geven in de huidige closures oorlog bij Java.</p>
<h2>Closures</h2>
<p>Wat is een closure? WikiPedia (<a href="http://en.wikipedia.org/wiki/Closure_(computer_science)">http://en.wikipedia.org/wiki/Closure_(computer_science)</a>) heeft de volgende nietszeggende definitie: &#8220;In computer science, a closure is a function that is evaluated in an environment containing one or more bound variables. When called, the function can access these variables.&#8221;. Hoewel deze definitie klopt, is hij niet echt duidelijk. Waar komt het op neer?</p>
<p>Bij een closure wordt een functie uitgevoerd in een andere context dan waarin deze wordt gecreëerd. Deze zogenaamde “function context” wordt bij het creëeren van de functie bij de referentie naar de functie opgeslagen. Dit betekent dat als iemand deze referentie te pakken krijgt en de functie aanroept, de variabelen uit de context waarin de functie gemaakt is, beschikbaar zijn.</p>
<p>Voordat ik concreter wordt, wil ik nog even aangevan dat closures niet nieuw zijn. In vrijwel elke mainstream taal zit een soortgelijke constructie. Ook in Java, namelijk met anonymous inner classes, maar andere talen, zoals Smalltalk, JavaScript en Ruby bieden veel meer flexibiliteit.</p>
<p>Nog steeds nietszeggend? Dan maar een codevoorbeeld (JavaScript):</p>
<pre class="brush:javascript">
&lt;html&gt;
  &lt;head&gt;
    &lt;script type="text/javascript"&gt;
      function initPage() {
        var counter = 0;
        window.onclick = function() {
          alert("Click #" + ++counter);
        };
      }
      window.onload = initPage;
    &lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>Wat gebeurt hier? Om te beginnen zijn functies in JavaScript first class objecten, in tegenstelling tot in Java, waarin methoden altijd onderdeel van een object zijn. Dit betekent onder andere dat je naar een functie kunt refereren, of deze referentie in een variabele kunt stoppen om deze daarna rond te gooien. Dit kun je zien aan de regel &#8220;window.onclick = &#8230;&#8221; waarin een object van het type function aan de onclick property van het window object toegekend wordt.</p>
<p>Wat (hopelijk) ook opvalt is dat er een function in een andere function gedeclareerd wordt. In dit voorbeeld spreken we van een anonymous inner function. Dit is een belangrijk detail, aangezien dit voor de JavaScript interpreter betekent dat er een closure gecreeerd moet worden. Wat betekent dit?</p>
<p>Kort gezegd betekent een closure dat bij de referentie naar de anonymous inner function, alle variabelen uit de enclosing scope bewaard blijven. Vandaar de naam closure. Deze variabelen vormen de function context welke vanaf nu een deel van de functie geworden. Elke keer als je deze functie aanroept, zijn de variabelen in de function context beschikbaar.</p>
<p>Wat is het nut dan van deze closure? Nou, de variabele &#8220;counter&#8221; heeft een function scope en verdwijnt op het moment dat de functie eindigt. Bij een event handler zoals in bovenstaand voorbeeld betekent dit dus dat de variabele op het moment van de klik niet bruikbaar is, aangezien het click-event niet in dezelfde stack plaatsvindt. Dit betekent dus dat je zonder closures een globale variabele nodig hebt om een simpel tellertje te maken. Met closures heb je deze beperking niet, want de variabele counter blijft bewaard en de ++ operator werkt de variabele in de function context bij, zodat het ook een echte teller is.</p>
<h2>Conclusie</h2>
<p>Closures bieden dus de mogelijkheid om stack confined variabelen te bewaren over meerdere stacks heen en zijn daardoor dus zeer geschikt voor event handlers. Dat is ook de reden dat ze in JavaScript veel gebruikt worden. JavaScript wordt voornamelijk gebruikt voor het koppelen van event handlers aan buttons etc. Daarnaast biedt het een mooie compacte syntax.</p>
<p>Volgende keer kijken we naar de Java closures initiatieven.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smart-java.nl/blog/index.php/2008/08/29/closures-introductie/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
