»
S
I
D
E
B
A
R
«
NamedParameters
Jun 2nd, 2009 by Rikard Qvarforth
Parametrar i allmänhet är rätt svårtydliga speciellt om det är parameterar som är av rå-typ tex String, int etc. Som Martin Fowler så kan det vara ett tecken på
primitive obsession
Men ett annat problem med parametrar är själva ordningen, hur tvingar man en klient att rätt parameter kommer i rätt ordning?

Ett sätt är att skapa named parameter i java.

Här nedan har vi vår test klass över den lilla klassen Person. Persons konstruktor tar i dags läget in två parameterar förNamn och efterNamn.

 Java |  copy code |? 
01
public class PersonTest {
02
 final static String firstName = "Firstname";
03
 final static String lastName = "Lastname";
04
 
05
 @Test
06
 public void shouldCreatePersonWithFirstNameAndLastName() {
07
 Person person = new Person(firstName, lastName);
08
 assertThatNameIsSetOnPerson(person, firstName, lastName);
09
 }
10
 
11
 @Test
12
 public void shouldCreatePersonWithParameterName(){
13
 Person person = new Person(firstName(firstName).lastName(lastName));
14
 assertThatNameIsSetOnPerson(person, firstName, lastName);
15
 }
16
 
17
 @Test
18
 public void shouldCreatePersonWithDiffrentFirstName(){
19
 String karin = "Karin";
20
 Person person = new Person(firstName(karin).lastName(lastName));
21
 assertThatNameIsSetOnPerson(person,karin, lastName);
22
 }
23
 
24
 private void assertThatNameIsSetOnPerson(Person person, String firstName, String lastName) {
25
 assertThat(person, notNullValue());
26
 assertThat(person.getFirstName(), is(firstName));
27
 assertThat(person.getLastName(), is(lastName));
28
 }
29
 
30
}
31

 Java |  copy code |? 
01
02
package domain;
03
 
04
public class Person {
05
 
06
 private String firstName;
07
 private String lastName;
08
 
09
 public Person(final String firstName, final String lastName) {
10
 this.firstName = firstName;
11
 this.lastName = lastName;
12
 }
13
 
14
 public Person(Name name) {
15
 this.firstName = name.firstName;
16
 this.lastName = name.lastName;
17
 }
18
 
19
 public String getFirstName() {
20
 return this.firstName;
21
 }
22
 
23
 public String getLastName() {
24
 return this.lastName;
25
 }
26
 
27
}
28

 Java |  copy code |? 
01
02
 
03
package domain;
04
 
05
public class Name {
06
 
07
 public final String firstName;
08
 public final String lastName;
09
 
10
 private Name(String firstName, String lastName) {
11
 this.firstName = firstName;
12
 this.lastName = lastName;
13
 }
14
 
15
 public static NameBuilder firstName(String firstName) {
16
 return new NameBuilder(firstName);
17
 }
18
 
19
 public static class NameBuilder{
20
 
21
 private String firstName;
22
 
23
 private NameBuilder(String firstName){
24
 this.firstName = firstName;
25
 }
26
 
27
 public Name lastName(String lastName){
28
 return new Name(firstName,lastName);
29
 }
30
 }
31
 
32
}
33
 
34
Google-Collections 1.0 release candidate!
Apr 8th, 2009 by Rikard Qvarforth

Nu är den äntligen här som Rc Ettan för google collections :)

Här är release notes för 1.0 RC

Laddas ned på denna länk google-collect-1.0-rc1.zip



  • com.google.common.annotations package with new annotations for marking types as gwt compatible (GwtCompatible, GwtIncompatible), and marking a type or member as being visible only for testing (VisibleForTesting)
  • Joiner, which joins pieces of text together, replacing the old static methods on the Join class.
  • Predicate.instanceOf(Class) returns a Predicate that evaluates to true if the object being tested is an instance of the given class.
  • MutableClassToInstanceMap and ImmutableClassToInstanceMap, which map a class to an instance of that class.
  • ImmutableSetMultimap is a SetMultimap with reliable user specified key and value iteration order.
  • Maps.difference(…) computes the difference between two maps, returning the result as a MapDifference.
  • Collections2.transform(…) is the Collection-based equivalent of Iterables.transform(..), and returns the Collection that results from applying a Function to each element of a given Collection.
  • New ImmutableMultimap.of(..) static methods were added to quickly create immutable maps of specified values.
  • ImmutableMultimap.Builder has a new putAll(…) method to store another multimap’s entries in the built multimap.
  • Multisets.immutableEntry(E, int) returns a new immutable Multiset.Entry with the specified element and count.
  • Multiset has new setCount() methods that can be used to add or remove the necessary number of occurences of an element such that the element attains the desired count.


  • http://code.google.com/p/jsr-305/)
  • Deprecated Functions.TO_STRING removed in favor of Functions.toStringFunction().
  • Functions.toHashCode(). This isn’t a commonly used function, and can be implemented by hand if needed.
  • Preconditions.checkContentsNotNull(…)
  • Predicates.isSameAs(Object). This wasn’t commonly used, and can be easily implemented by hand.
  • The following methods were removed from Iterables: containsNull(Iterable), emptyIterable(), limit(Iterable, int), rotate(List, int), skip(Iterable, int).
  • The following methods were removed from Iterators: containsNull(Iterable), emptyListIterator(), limit(Iterator, int), skip(Iterator, int).
  • The Multimaps.index(..) method that takes a multimap as the third argument has been removed.
  • The Sets.SetView constructor is no longer public (this was an oversight).
  • Multiset.removeAllOccurrences(Object). You can replace usages of this with elementSet().remove(Object).
  • AbstractMapEntry. Most usages of this can be replaced with java.util.AbstractMap.SimpleEntry/SimpleImmutableEntry provided their keys and values are directly stored in the Entry instance.
  • Constraints, Constraint and MapConstraints.
  • CustomConcurrentHashMap.
  • Serialization.


  • ConcurrentHashMultiset.
  • Predicates.isEqualTo(T) renamed to Predicates.equalTo(T)
  • AbstractIterator now extends UnmodifiableIterator.
  • The constructors on ArrayListMultimap, HashBiMap, HashMultimap, HashMultiset, ImmutableBiMap, LinkedHashMultimap, LinkedHashMultiset, LinkedListMultimap, TreeMultimap, and TreeMultiset were removed in favor of new static create() methods which provide type inference. The various static creation methods on Multimaps were removed in favor of create() methods on each Multimap class.
  • Iterators.newArray(..) and Iterables.newArray(..) were renamed to toArray(..).
  • The instance methods in Ordering are all now final.
Download
TDD DSL – make it production code
Mar 8th, 2009 by Rikard Qvarforth
Inom vårt team fick vi högst prioterat in en bugg som låg mitt i våran domän model, våran prismodell! Detta leder till att en heldrös objekt är inblandade i skapandet av diverse priser. Jag börjde titta på de tester vi har på just på det området inom vår domän och insåg att det var otroligt mycket kod som var duplicerad samt svårtydlig. När sedan bug rättning storyn startade i sprinten tittade jag på olika lösningar inom tdd att arrangera våra fixturer.

Jag såg följande alternativ:

  • ObjectMother - en static factory lösning som ger utvecklaren den fixtur som behövs inför sitt enhetstest
  • BuilderPattern - en DSL liknande lösning att ge utvecklaren en flexibel fixtur test data lösning baserat på standarn val.
Jag måste ge Nat Pryce super kred! killen är grym! Såg hans exempel på Builder pattern för sina texturer och insåg att detta är det spår vi måste ta.

Efter närmare undersökning så insåg jag att vi redan hadde en hybrid av Object Mother genom en abstract class som inehöll static metoder enligt “create” så som:

createCampaingWithEnclosingBudgetWtihLimitOnClick();

Dessa metoder förökade sig som svampar! genom att varje test i sig är unikt, vilket är bra! Dock leder detta till en Object Mother som är mer som en sur gammal mormor.

Genom att i ställer ta en annan approch genom builder-pattern och att ha smarta default-värden. Plus att ge (enligt tips från Nat pryce) Builders i Builders anrop slippa se en harang av build().build().build(), så får man ett fluent dsl i sin test fixtur. Ruskigt fint för ögat samt att man har den trevliga sideffekten att sina test builders kan leva i test sourcen tills man inser att detta borde ligga i produktions koden direkt!

Ett exempel (Campaign är aggregat objekt):

 Java |  copy code |? 
1
2
//Given
3
Currency sek = Currency.getInstance("sek");
4
Long id = new Long(1L);
5
Campaign campaign = aCampaign(id).andCurrency(sek).
6
                   withBudget(aLimit(100L).withEvent(aEvent().asClick())
7
                                                       .withPrice(50D).build()
8

En annan sid effekt blir att varje test inte behöver lägga till ett ytterligare createMetod bara pga av ett ytterligare test fixtur. Lägg til buildern med ett smart default värde/builder istället!

Som Josua Bloch propagerar borde varje new vara inkapslat av en builder, så låt nu dina test builders blir riktiga medlemmar av din domän istället!

Finns ruskigt bra argument varför man ska kapsla in new operatorn! men det i en annan post :)

Effective Java Reloaded
Mar 7th, 2009 by Rikard Qvarforth
Preconditions, Design by Contract
Mar 6th, 2009 by Rikard Qvarforth
Är det någon mer än jag som hatar dessa ständiga null check kollar i java, i enlighet med Design by contract?!

Och är det någon som har skapat någon “kollaOmNull”-metod som återfinns i någon util klass?

om ja på något av alternativen så kolla in detta i GoggleCollections…


 Java |  copy code |? 
1
2
public Person(final Long id, final String name, final Integer age) {
3
 
4
Preconditions.checkArgument(id != null);
5
 
6
}
7


Samt om du vill se i en lista eller dylika om det har smygit sig in något null värde.


 Java |  copy code |? 
1
2
public void setNames(List<String> names){
3
 
4
Preconditions.checkContentsNotNull(names,"A null name was in the Collection!");
5
 
6
this.names = names;
7
 
8
}
9
En myckettrevlig klass för att kolla preconditions finns i flera olika varienter.

Om ni inte vill ta in hela google-collections så ta bara java sourcen och klistra in ;) (copy paste kodning är bra ibland

kommentarer, har ni inte en util-klass liggandes någonstans som gör något liknade?
Google-Collections Transform
Mar 5th, 2009 by Rikard Qvarforth
Hej! satt idag på jobbet och insåg att man skyfflar från ett format till ett annat med alla möjliga snurror. Produkt.getId() till –> List produktIdList;

Såg att Goggle-Collections har en transform metod så det hela resulterade i detta:
 Java |  copy code |? 
01
02
package functions;
03
 
04
import com.google.common.base.Function;
05
 
06
import domain.Person;
07
 
08
public final class TransformFunctionPersonToId implements Function
09
 
10
{
11
 
12
@Override
13
 
14
public Long apply(final Person personToTransform) {
15
 
16
return personToTransform != null ? personToTransform.getId() : null;
17
 
18
}
19
 
20
}
21
... samt lilla testet..
 Java |  copy code |? 
01
02
@Test
03
public void testShouldTransformListOfPersonToListOfLong(){
04
 
05
//Given
06
 
07
Person one = new Person(1L,"pär",12);
08
 
09
Person two = new Person(2L,"eno",22);
10
 
11
Person tree = new Person(3L,"leo",32);
12
 
13
Person four = new Person(4L,"pia",42);
14
 
15
List
16
 
17
persons = new ArrayList
18
 
19
();
20
 
21
persons.add(one);
22
 
23
persons.add(two);
24
 
25
persons.add(tree);
26
 
27
persons.add(four);
28
 
29
//When
30
 
31
List<Long> personIdList =
32
 
33
Lists.transform(persons, new TransformFunctionPersonToId());
34
 
35
//Then
36
 
37
Long test = 1L;
38
 
39
for(Long id : personIdList){
40
 
41
System.out.println("ID: "+id);
42
 
43
Assert.assertEquals(id.longValue(),(test++));
44
 
45
}
46
 
47
}
48
EJB3 DTO dödaren
Mar 2nd, 2009 by Rikard Qvarforth
När EJB3 specifikationen kom och den första implementationen av hibernate var ute. Så var ett av sälj argumenten det att vi nu kan göra oss av med DTO’erna en gång för alltid.
Experterna glömde ett scenario där detta inte gäller …
I ett projekt skulle vi införa EJB3 med hibernate som den nya arkitekturen. Istället för den DTO lösning som fanns på plats samt den lite nyare hibernate lösningen med open-session-in-view. Vi läste på oss, tog in experter, gick kurser och vi kom fram till följande:
1) Open-Session-in-view, skall vi inte ha kvar. På grund av många skäl. Hum en till artikel månne ? :P
2) Vi kan strunta i DTO’erna för istället har vi vår domän och dess entiter som vi för upp till vyn
Vänta nu! Pausa och spola tillbaka! Våra domän objekt aka entiteter upp direkt till vy lagret! är inte det ett komplett lagbrott mot SoC (Separation of concerns)? Enligt min uppfattning är ett av huvudsyfterna med DTO’er att just upprätthålla detta.
Jaja.. det ska nog gå bra ”alla” säger ju att EJB3 tar bort behovet av DTO’erna…



As time goes by ..
När vi började implementera den nya arkitekturen gick allt som en dans i och med de hyfsat enkla användarfallen så ser man inte faran med entiteter uppe i vyn.
Men efter en tid så började produkt ägaren komma med bizz-regler som kräver mer av våran domänmodell. Vi behöver nu applicera dessa på våra aggregat objekt för att upprätthålla regeln/”statet”.
Och hur gör vi detta då? nu när vi har öppnat upp våra pojo entiteter som rena rama seven-eleven butiker?
Inte nog med det mer och mer data måste upp till vyn och inte bara från en viss entitet utan från flera.
Tänker man efter så är detta oftast fallet. Användaren vill inte bara se data från ett eller flera Person objekt utan mer som en tårtbit ur vår domän ”kaka” modell.
Tex ett Person objekt med sin varukorg med statistik över sina produkter samt sina kontrakt med sina nuvarande kunder.

Ni märker väll att det blir problematiskt?…


Storm at the horizon ..


Just detta ledde till en hel drös med LazyInitException’s som skedde på grund av att vyn försökte plocka fram data genom våra pojo entiteter som i sin tur var en hibernate proxy.

-Ni kommer väll ihåg transaktions gränsen har vi passerat..
Vår lösning på detta var tyvärr inte att stoppa denna domän massflykt till vyn utan istället implementera en assembly-phase lösning med så kallade fetchhints på server sidan. Med dessa fetchhints skulle vyn kunna styra vad den ville ha från våran domän.
Dock ledde detta till mer problem genom att vi drog upp hela eller delar av databasen fast vi ville bara ha viss data. Samt hur skulle vi göra när vi vill ha data långt ned i objekt-trädet?


Bigger problems ..


Men enligt min uppfattning är inte detta det stora problemet. Problemet blir verkligen farligt när vi inte kan applicera våra bizz regler pga våra pojo liknande entiteter. Publika “setters” samt entiteter som endast ska

kommas åt genom aggregat objekt strövar fritt ute i vyn.


Hope spells DTO?..


Så summa kardemumma:

1) Använd DTO’erna när du behöver visa data från fler än en entitet.
2) Ha inte ORM annoteringar på set/get utan på fält nivå! Jag ska bli ännu tydligare! Använd INTE PUBLIKA SETTERS PÅ DINA ENTITETER.
3) Om du skickar upp entiteter till vyn gör det endast för att visa data.
Vid CRUD använd DTO’erna eller möjligtvis värde objekt.
Kolla gärna in qi4j som har en annorlunda approch.



Så visst behövs DTO’erna i någon form jag säger inte att DTO’erna är en “silver bullet”

men lär dig av mina misstag och tänk till före :P



EJB3 DTO killer …
http://www.theserverside.com/tt/articles/article.tss?l=MigratingJDBC
»  Substance: WordPress   »  Style: Ahren Ahimsa
© copyright@alltomjava