Wednesday, January 28, 2009

pet project idea

Implement a 'bean-mapper' a la Dozer, but instead of using the xml files, use dynamic proxies, a la LiquidForm.

Tuesday, January 27, 2009

Failure

Failure

"The only failure is the failure to learn from failure" -- Kevin Everett FitzMaurice

A friend of mine notice that in a big company, which recently decided to embrace agile and use Scrum, the Scrum practices are applied in a mechanical way. Actually he called it a 'theater', and he said that the 'agile principles' are important. A colleague had a similar observation, that Scrum is applied in an american-indian-ceremony kind-of way, expecting that the results will fall out of the sky.

Maybe this is related to the 'Shu Ha Ri' training cycle, which:
TheThreeExtremos lately seem to be recommending a ShuHaRi approach to XP: First, follow all the practices. Then, realize TheyreJustRules, and change them (i.e. break some of the original rules). Finally, you don't need to think about the rules anymore. -- GeorgePaci

But in day-to-day business, it is just sloppiness. People don't understand that they are on a learning journey, they don't understand why are they following the practices/rules. Some don't want to learn, they just one to get the job done and go home. Many people are just happy with Ship-It. We've done, it, we are happy, let's go home. No retrospection, no how-can-we-do-it-better-next-time, no 5-whys. There is no striving towards elegance, to do things better. No passion, no motivation. Probably that's why retrospective are the first to be dropped/disregarded.

Does this mean that Agile/(Scrum?) is a culture-thing? How can we change a 'not-my-problem' culture? How can we stop sinking in a pool of problems? How can we start carrying?

ps. via rangawald's delicious, I found Taming Perfectionism.

Friday, January 16, 2009

The Membrane

Suppose we have 4 coupled/chained objects: A, B, C, D, accessible through the properties A.B.C.D, and the objects have the following properties:

A: B, A1, A2
B: C, B1, B2, B3
C: D, C1, C2
D: D1, D2, D3

Usually within a certain area/component, we don't need all that object tree, but just a projection/subset of it: eg. IView { A1, B1, C1, D1. }
In practice, the problem is that most of the people will use/scatter these properties all over their code, leading to maintenance monsters:
- navigation is all over the place, violating the 'Law of Demeter'.
- Testing is getting a lot more difficult: in order to test a user of IView you need to instatiate A, B, C, D, these might have good constructors which force you to instatiate other X objects, etc.
- The amount of code using chained objects/train wrecks will crush future refactorings: if you'll want to reverse the navigation from B.C to C.B, you'll have to change all the usage points, the same goes for changing a data type.

Possible solutions:
a. Define the projection as required by that component/use case, eg IView { A1, B1, C1, D1 } (properties, or getter/setter, etc.)
- Define a repository service IRepository.get(...) -> IView
- Work against your abstraction IRepository/IView

The IView/IRepository could build through:
- DTOs mapping (a la dozer & co.)
- wrap & lazy fetch:
View {
ctor(A a) { _a = a; }
A1 { _a.A1 }
B1 { _a.B.B1}
C1 { _a.B.C.C1 }
D1 { _a.B.C.D1 }
}
(a pretty slick solution might be build with LINQ expressions)
In this way we have isolated our component from external changes, we are depending only on our IRepository/IView, future refactorings will afect only that area.
The IRepository/IView abstractions represent the membrane to the external world. (Ralf refers to the pattern as 'external adapter', probably refering to Alistair Cockburn's 'Hexagonal Architecture' paper, I prefer the Alan Kay's metaphor).

b. Instead of defining the projection IView we could add the required operations on A. This has the benefit of aggregating/reusing common operations on A (usually a root entity).
In some cases it might lead to the polution of A: all the properties/operations beneath the A will emerge into A, transforming the tree into a list. Class A will become too big, containing its data, and n+ operations (C# has region-folding, smalltalk has protocols for organizing big classes)

Final thoughts:
- it is not about DDD/Tell don't Ask vs EJB/DTOs vs XXX, but is about isolation/visibility.
- (Unit) Testing asap helps a lot identifying architecture/design smells.

Friday, January 09, 2009

toString or not toString

suppose we have an Id class, which used as a 'pointer' to some persistent entities.

abstract class Id {
T _raw;
Id(T raw) { _raw = raw; }
@Overrride void toString() { return _raw.toString(); }
}

And the Object#toString() documentation says:
/**
* Returns a string representation of the object. In general, the
* #toString method returns a string that
* "textually represents" this object. The result should
* be a concise but informative representation that is easy for a
* person to read.
* It is recommended that all subclasses override this method.
*
* The #toString method for class Object
* returns a string consisting of the name of the class of which the
* object is an instance, the at-sign character `@', and
* the unsigned hexadecimal representation of the hash code of the
* object. In other words, this method returns a string equal to the
* value of:
* getClass().getName() + '@' + Integer.toHexString(hashCode())
**/

What is the problem?

* we heavily use these Ids in a *lot* of places
* id.toString() is used both for Id -> String conversion, as a part of our design and as textual representation for debugging/logging
* to subclasses AID and BID will have the same textual representation, making future debugging/logging more confusing then necessary
* if we enrich the Id with more data (eg. a timestamp, or entity version, etc.) we can no longer not add this extra data to its textual representation (eg. logging), since toString() is also used for conversion
** it is very hard to find all the usages of the toString method, since every IDE (and the compiler too) considers this method belonging to the Object and not to the abstraction Id (that's why the @Override is there)
*** if we would have worked in a TDD kind-of way, we probably would have started with an interface, IUniqueId, to which we probably would have added a method asString()

concluding advice: when you model your own domain language/design, be careful what you override.

Thursday, November 27, 2008

Pragmatic Compromise

Have you noticed that all the guys who are advocating a compromise code quality vs. speed,
are not the guys who are going to maintain that code? Have you noticed that these guys bully you into delivering features fast, and later they come complaining ' Why is the quality so poor? '.
Even if quality is not seen as corporate asset, make it a part of your professional ethics.

Tuesday, November 11, 2008

DynamicQuery

Has anybody tried to do an EJB DynamicQuery implementation a la groovy, using a DynamicProxy ?
(post inspired by AutoBoundary proxymatic)
Apparently yes: check-out the LiquidForm.
There are some other alternatives, but java is not there yet.

Monday, November 10, 2008

Scrum Log

After reading/watching an impressive amount of presentations from Henrik Kniberg: parleys, slides, technical-debt, bootstraping scrum and xp in a crisis, scrum checklist, and more, I've decided to keep a personal iteration log.
It's amazing how much clarity you get at the end of an iteration: the retrospective.

Monday, November 03, 2008

Dark Syntax Highlight

(in RGB)
Brackets: 128,255,0
Keywords: 217,167,15
Comments: 0,185,0
Tasks,ToDos: 0,255,0

Thursday, October 23, 2008

API Usability

The success of an API/component largely depends on its usability: is it easy to create, is it easy to handle, is it easy to wire? Is it easy to make a mistake? Are some contracts unclear ?

The first feedback we get from (unit-)tests. Unfortunately a lot of people don't do that.
Another point is that the tests (partially) lie about how the component is used: they represent how the author assumes the component will be used. Feedback from customers and refactorings should follow...

Wednesday, October 22, 2008

Filter support for PropertyConfigurator

The PropertyConfigurator class in log4j does not support filters and few other advanced configuration options. There was a need to add logging filters to a legacy Java app, but modifying the application code to use DomConfigurator was out question. The alternate approach was to directly add filter support to the PropertyConfigurator class in log4j.

Filters are chained to an appender in a specified order. However, the runtime representation of a .properties files is basically a hashtable, and there is no ordering defined on the keys of a plain hashmap. Any implicit ordering of the lines in the properties file is lost when it is parsed. To overcome this, filters are identified by unique IDs, and filters are added to the appender in the lexicographic order of the IDs.

Keeping the notations used by the log4j source code, filters are configured as follows:

log4j.appender.appenderName.filter.ID=fully.qualified.name.of.filter.class
log4j.appender.appenderName.filter.ID.option1=value1
...
log4j.appender.appenderName.filter.ID.optionN=valueN


You can download the patch directly from the log4j bug tracker. It can be applied to the current HEAD of the 1.2 branch, more exactly to 1.2.15.

Friday, October 10, 2008

Coder

Written code is a cost, since it has to be maintained. Less code, less maintenance.
Maybe we should call developers 'anti-coders'.

Tuesday, August 19, 2008

Option/Maybe monad is a generic NullObject

I've just reviewed the NullObject and Visitor post. It is so similar with the Option/Maybe monad.
ps. Thought's on Validation: Scala/liftweb has an nice Can.

Monday, August 11, 2008

Scala Marketing Challenge

Josh Suereth would like to improve the Scala's marketing strategy.
This is a tough sell. If we look at the Change Function:

ChangeFunction = F(PerceivedCrisis/PerceivedPainOfAdoption).

(btw. read Erik Meijer's paper: 'Confessions of a Used Programming Language Salesman', it's really, really good.)

So we'll have to ask ourselves what problem is Scala trying to solve, and how much it'll cost. IMHO, Scala is trying to make programming easier. It partially addresses the concurrency problem, but it is not its main-focus, I would say is the ScalaActors are a good side-effect of Scala's good (language + library) design.

What we'll have to pay in order to make the 'switch': the syntax is slightly different. Functions are 1st level citizens. (but functions/closure are scary). Operator overload is also scary (funny enough, method overload is not scary: we are afraid of symbols but we are not afraid of words). Then we have for a good generic support we have 'Generics of a Higher Type', type covariance/contra-variance. Pretty scary... booh! Did I say that IDE support is not yet at java's level?

On the other side we have a huge number of java developers. They are satisfied. Not really happy, not really sad. Ok, java is not that great, but it has been like this for years, why change? To be more effective? Probably to sell that to a manager you'll need 5 independent studies to show that scala is better then java and you'll need at least one big company to push the language. ('if they use it, we could use it too')

Regarding concurrency: a lot of java developers have problems to right correct code, so probably concurrency is the least of their problems. Other developers we'll say 'we have java.util.concurrency'.
If you look at the package you'll see they offer concurrency primitives, and to write shared-state concurrent programs is very hard. You'll have to think a lot more about object isolation and the threading context.

In conclusion:
- UserPerceivedCrisis: small
- PerceivePainOfAdoption: big
ChangeFunction -tends-to-> small.

sorry, scala...


Friday, August 08, 2008

Poka-yoke API Design

API Design should be Poka-yoke.
And if we look what zen aesthetic means to people, a good design is zen: clean, simple, minimalistic.

Thursday, July 31, 2008

hg vs git, pull+merge vs rebase

@pastebin
GIT encourages rebasing, which leads to rebasing of your public and other people's
code. This is bad.

Mercurial, which hashes a changeset's place in history as well as it's
content, discourages rebasing. Rebasing happens in private with mq patch queues.
Public trees are merged. This is good.

Either style is possible with both tools. The difference is the default emphasis.

Defaults matter.

Linus Torvalds on rebasing:

* http://kerneltrap.org/Linux/Git_Management
* http://lwn.net/Articles/291302/
* http://lwn.net/Articles/291303/
* http://lwn.net/Articles/291304/


Matt Mackall on synchronizing (pull + merge, don't push, don't rebase):

* http://www.selenic.com/pipermail/mercurial/2008-July/020116.html
* http://www.selenic.com/pipermail/mercurial/2008-July/020131.html

Thursday, July 24, 2008

Scala Exercises

I have completed Tonny Morris Scala exercises. (maybe I'll put them on the svn as well, or maybe mercurial ?)...
Anyway some observations:
- it felt like doing the 'Little Schemer' in Scala.
- after doing 3-4 exercises, you feel the need to use/implement fold_left/fold_right.
- maximum is buggy: what's the maximum on an empty list? (the maximum found must be contained in the list;reasoning related to 'Noumenal Null'). I believe that this exercise is a 'tricky question' and instead of throwing an exception, or returning Nothing or Int.NaN, probably the signature should be changed to : maximum(x: List[Int]) : Option[Int]

- In the List's implementation of map/filter/... they use instead of pattern matching if x.isEmpty ... else ( do_something(x.head, x.tail). Probably it's faster than pattern decomposition.

Thursday, June 12, 2008

Lack of Fit

Over the J. Paul Morrison's article I found the following quotation:

In the early part of his book "Notes on the Synthesis of Form", Alexander describes the concept of "fit". He makes the point that, as humans, we find it very hard to detect "fit", but are well-adapted to detecting "lack of fit". Think of trying to decide if the edge of a piece of wood is straight: the natural thing to do is to put it against a straight surface and see if any gaps show in between. As we try to improve things by reducing the misfit factors, we soon discover that these factors tend to be interrelated: fixing one may exacerbate another, so there is a continuous process of compromise between a number of less than ideal solutions. Intuitively, the less interrelated the misfit items are, the easier it will be to reach a state of acceptable fit. This means that our only hope of reducing misfit factors is if these factors occur in clusters such that the connections between clusters are relatively loose. In application development, this works best if the infrastructure software components also define boundaries between misfit factors.

maybe that's why I'm so critical....
btw. I've started reading J. Paul Morrison's book. I like it, I recommend it.

Thursday, May 22, 2008

LanguageFear

I've just read Martin Fowler's article ParserFear. So, Why Not a Parser for a DSL?
Martin didn't quite specified why we need a DSL:
- Is it for business people to specify their requirements?
- Is it just 'readable' code, for programmers ?
I assume that in both cases we are trying to solve a customer's problem, by building an easy to maintain.

Let's say we use XML. Well that is a bad idea, and Martin knows it: XML is not the answer. It is not even the question. And to write XML is a difficult thing to sell, to a business-man.

Let's say that we go the ANTLR way. Which means from all the languages which are out there, none fits our needs, so we have to build our own. Ok, let's say we've build one. But now we need for our users an editor. We might need good error messages, syntax highlight, the possibility to reuse blocks of code from our programming language. Later we will need to extend our language, without hurting the users. And on the other side, the code generated will be difficult to maintain or to build abstractions on it. That's because code generation is just a raw, automatic, copy-paste machine: it doesn't build any higher-order abstractions. And the direction seems to be wrong: instead of helping our customer, we are baby-sitting our language/editor/infrastructure.

Or we go with embedded DSLs: some languages are better then others. And some languages can be easily integrated with others. Some have heavier syntax making more difficult to create a clean DSL, some are more lightweight, making a perfect match for DSLs.

Or we can go with a 'building material', a 'programmable programming language', or something similar.

Why do people fear of learning of a new language, but they invest uncountable hours in building sand-castles. Even Martin agrees: be a polyglot.

Friday, May 02, 2008

Validation Combinators, a F# prototype

Suppose we have the following situation: we have a bag/set of named objects which have to be validated. These objects are primitives, let's say strings, for our sample.
Some strings can be validated as 'standalone' some need to be validate against each other. This validation doesn't belong to the domain for several reasons.
Regrettably, the existing frameworks don't suite our needs.

Trying to decompose the problem, we need:
- a way to get object out of the bag, by name
- a validation method/function which can validate one or more objects
- if the validation fails, we want to collect a 'failed validation message'
- we want to compose these validations: and, or, not, xor, etc...

Let's put that in code:

1 #light

2 open System

3 open System.Collections.Generic

4 open System.Text

5

6 type get_by_name = String -> String

7 type accumulate_message = String -> unit

8 type validator = get_by_name -> accumulate_message -> bool

We use F# light syntax, and open some .Net namespaces, define the required function types: I really like this kind of 'aliasing': give name to a type, since being based on type inference, is not obtrusive.It is not like a java/c# Interface, where the interface must be implemented. In our case, if we have another function with a signature matching our type, we can use that function as the required type. (we could say is a type-safe duck-typing)

10 let _and_ (x : validator) (y : validator) = (fun (get_value_from_bag : get_by_name) (accumulate_validation_message : accumulate_message) ->

11 let ok_x = lazy x get_value_from_bag accumulate_validation_message

12 let ok_y = lazy y get_value_from_bag accumulate_validation_message

13 Lazy.force ok_x && Lazy.force ok_y)

14

15 let _or_ (x : validator) (y : validator) = (fun (get_value_from_bag : get_by_name) (accumulate_validation_message : accumulate_message) ->

16 let ok_x = lazy x get_value_from_bag accumulate_validation_message

17 let ok_y = lazy y get_value_from_bag accumulate_validation_message

18 Lazy.force ok_x || Lazy.force ok_y)

19

20 let _not_ (x : validator) = (fun (get_value_from_bag : get_by_name) (accumulate_validation_message : accumulate_message) ->

21 let ok_x = x get_value_from_bag accumulate_validation_message

22 not ok_x)

23

24 let _xor_ (x : validator) (y : validator) = ((_not_ x) |> _and_ y ) |> _or_ (y |> _and_ (_not_ x) )

Having defined what a validator is, we have defined functions to combined them: and, or, xor. In order to simulate the behavior (a and b -> b is evaluated only if a is false), we cache the result of a validator in
a lazy value: the value is computed only once, delayed, on demand. In the xor combinator we have used another DSL-friendly feature: partial-function application: ie. if we have a function f(x, y) -> z we could write this as: y |> f x.

Ok, let's see how it works. We define a validator:

27 let is_starting_with (start : String) (name : String) = (fun (get_value_from_bag : get_by_name) (accumulate_validation_message : accumulate_message) ->

28 let value = get_value_from_bag name

29 let ok = value.StartsWith(start)

30 if not ok then

31 let msg = string.Format("{0} '{1}' doesn't start with {2}", name, value, start)

32 accumulate_validation_message msg

33 ok)


Lets define a map of name -> values, and a message accumulator:

36 let map = new Dictionary()

37 map.Add("customer","ali")

38 map.Add("buyer", "baba")

39 map.Add("vendor", "nono")

40

41 let get_value (key : String) : String = map.Item(key)

42

43 let acc = new StringBuilder()

44 let accumulate (msg: String) : unit = acc.AppendLine(msg) |> ignore


Lets create a more complex validator:

46 let x = ("customer" |> is_starting_with "a") |> _and_ ("buyer" |> is_starting_with "b") |> _and_ ("vendor" |> is_starting_with "v")

That's really readable, isn't it?

And we can evaluate it:

48 printfn "evaluation: %b messages: %s" (x get_value accumulate) (acc.ToString())

49

50 System.Console.ReadKey()


ps. Look at a better example in a Good Video: "Composing Contracts: An Adventure in Financial Engineering".
pps. here is the code.