# HG changeset patch # User japod@localhost # Date 1222768772 -7200 # Node ID 83e731257bdc774ed9892f7b639ab8506140006c # Parent 37c9921c653e4801c1696ba1a41af0111ada8424 updating solution 07 to 1.5 diff -r 37c9921c653e -r 83e731257bdc task1/solution07/src/org/apidesign/apifest08/currency/Convertor.java --- a/task1/solution07/src/org/apidesign/apifest08/currency/Convertor.java Tue Sep 30 11:50:09 2008 +0200 +++ b/task1/solution07/src/org/apidesign/apifest08/currency/Convertor.java Tue Sep 30 11:59:32 2008 +0200 @@ -20,7 +20,7 @@ * When the need comes to extend the semantics, one subclasses the ConversionRequest and/or ConversionResult classes. *

* This method can be called as many times as you like. - * A {@link Convertor} shall be considered immutable. + * A {@link Convertor} shall be considered immutable wrt calls to {@link #convert(org.apidesign.apifest08.currency.Convertor.ConversionRequest). * This method of a single {@link Convertor} can be called from many threads concurrently. * @param req the conversion request; mustn't be null * @return the result of carrying out the conversion request; never null diff -r 37c9921c653e -r 83e731257bdc task1/solution07/test/org/apidesign/apifest08/test/Task1Test.java --- a/task1/solution07/test/org/apidesign/apifest08/test/Task1Test.java Tue Sep 30 11:50:09 2008 +0200 +++ b/task1/solution07/test/org/apidesign/apifest08/test/Task1Test.java Tue Sep 30 11:59:32 2008 +0200 @@ -26,12 +26,24 @@ protected void tearDown() throws Exception { } + // + // Imagine that there are three parts of the whole system: + // 1. there is someone who knows the current exchange rate + // 2. there is someone who wants to do the conversion + // 3. there is the API between 1. and 2. which allows them to communicate + // Please design such API + // + protected static final Currency CZK = Currency.getInstance( "CZK" ); protected static final Currency SKK = Currency.getInstance( "SKK" ); protected static final Currency USD = Currency.getInstance( "USD" ); /** Create convertor that understands two currencies, CZK and * USD. Make 1 USD == 17 CZK. + * USD. Make 1 USD == 17 CZK. This is a method provided for #1 group - + * e.g. those that know the exchange rate. They somehow need to create + * the objects from the API and tell them the exchange rate. The API itself + * knows nothing about any rates, before the createCZKtoUSD method is called. * * Creation of the convertor shall not require subclassing of any class * or interface on the client side. @@ -48,7 +60,11 @@ } /** Create convertor that understands two currencies, CZK and - * SKK. Make 100 SKK == 80 CZK. + * SKK. Make 100 SKK == 80 CZK. Again this is method for the #1 group - + * it knows the exchange rate, and needs to use the API to create objects + * with the exchange rate. Anyone shall be ready to call this method without + * any other method being called previously. The API itself shall know + * nothing about any rates, before this method is called. * * Creation of the convertor shall not require subclassing of any class * or interface on the client side. @@ -64,6 +80,13 @@ return new ContractImposingDelegatingConvertor( convertor ).test(); } + // + // now the methods for group #2 follow: + // this group knows nothing about exchange rates, but knows how to use + // the API to do conversions. It somehow (by calling one of the factory + // methods) gets objects from the API and uses them to do the conversions. + // + /** Use the convertor from createCZKtoUSD method and do few conversions * with it. */ @@ -118,5 +141,37 @@ assertEquals( CZK, a2.getCurrency() ); } + /** Verify that the CZK to USD convertor knows nothing about SKK. + */ + public void testCannotConvertToSKKwithCZKUSDConvertor() throws Exception { + final Convertor c = createCZKtoUSD(); + + // convert $5 to SKK, the API shall say this is not possible + final Convertor.ConversionResult r1 = c.convert( new Convertor.ConversionRequest( new MonetaryAmount( 5, USD ), SKK ) ); + final MonetaryAmount a1 = r1.getNetAmount(); + assertNull( a1 ); + + // convert 500 SKK to CZK, the API shall say this is not possible + final Convertor.ConversionResult r2 = c.convert( new Convertor.ConversionRequest( new MonetaryAmount( 5, SKK ), CZK ) ); + final MonetaryAmount a2 = r2.getNetAmount(); + assertNull( a2 ); + } + + /** Verify that the CZK to SKK convertor knows nothing about USD. + */ + public void testCannotConvertToUSDwithCZKSKKConvertor() throws Exception { + final Convertor c = createSKKtoCZK(); + + // convert $5 to SKK, the API shall say this is not possible + final Convertor.ConversionResult r1 = c.convert( new Convertor.ConversionRequest( new MonetaryAmount( 5, USD ), SKK ) ); + final MonetaryAmount a1 = r1.getNetAmount(); + assertNull( a1 ); + + // convert 500 CZK to USD, the API shall say this is not possible + final Convertor.ConversionResult r2 = c.convert( new Convertor.ConversionRequest( new MonetaryAmount( 5, CZK ), USD ) ); + final MonetaryAmount a2 = r2.getNetAmount(); + assertNull( a2 ); + } + }