Monday, March 31, 2008

Thoughts on Validation Patterns

During my worked at project X, I've looked for several validation patterns.

The use case is: you have a view with several fields, you need to validate them all, collect all the error messages and focus on the 1st erroneous file.

Since the View represents of a view (projection) over the Domain (Model) the right thing to do is to put the validation in the Model.

The problem arises from the fact the in an ActiveController-PassiveView (aka Model-View-Presenter)
neither the Model nor the View have access to each other:

PassiveView <-- Presenter --> Model.

The latest frameworks use annotations/validators & reflection to map validations ViewField <->
ModelField. (it gets hairier if you need to validate accross several fields, or several objects).

Project X was a .Net project, and .Net 2.0 has a nice feature: implicit type inference for delegates.
Let me explain: if you define an delegate
public delegate R Func<R, A1>(A1 arg1);


and a method
void DoSomething<R,A1>(Func<R,A1> converter) {
... }


then you can pass *any* method which matches the signature of the delegate to the
DoSomething(...)
method.

public R MyConverter<R,A1>(A1 arg);

...
DoSomething(MyConverter) // this is valid
Basically, starting with .Net 2.0, closures/functions are 1st class citizens in C#, like any other 'normal' objects. (closures are objects, afterall), with some remarks:

- .Net/C# properties are not methods and cannot be used as such
- in java you have to write a *lot* of anonymous classes, making more difficult to see any benefit. (that's also why an Enumerating component is not appealing in java, in C# the compiler writes the anon. classes for you)

Having said that, we can do a 'manual' binding in Presenter:

ValidationService.bind(PassiveView.GetField(), Model.ValidateField, PassiveView.SetErrorOnField)

the function signature of bind would be
bind<T>(T candidate, Func<bool, T> validate, Action signalError) {
if (! validate(field)) signalError();
}

We can do some more variations on the thema, where the ValidateField will also give us a message saying what was wrong with the candidate.


Variation within variation: message in several languages, should the model be responsible for that, maybe should provide the id to an message which will be translate...

One smell is that, after we have validated the field, by the Model, we pass again the value back to
the model in order to update/create some objects/fields.

Another discussion we had is that a constructor/factory using exceptions for validating arguments is expensive and it fails too fast, since we want to collect all error messages.

So we could replace that with a 2-step process:
maybeValidArgs = factory.Validate(args);
factory.create(maybeValidArgs);
but this is too 'manual'.

Some static typing functional languages have a construct to explicitely define a nullable value. In a c#/java would be:

interface Option<T> {
boolean HasValue();
T GetValue();
}

class Some<T> {
boolean HasValue() -> always true;
T GetValue() -> always the value;
}

class None<T> {
boolean HasValue() -> always false;
T GetValue() -> always throws an exception;
}

Note: In java we have type erasure, so for None<?> we can use a Singleton object.

Now for validation use case we might:

interface Option<T> {
boolean HasValue();
T GetValue();
IEnumerable<String> Errors();// Danger in using Strings !!! String is a 'primitive/sealed' type, which you cannot extend.
}

class Some<T> {
boolean HasValue() -> always true;
T GetValue() -> always the value;
IEnumerable<String> Errors() -> always Empty;
}

class None<T> {
boolean HasValue() -> always false;
T GetValue() -> always throw;
IEnumerable<String> Errors() -> always the errors;
}

Basically HasValue() has the same semantic with IsEmpty(Errors()).
We could change the pull - with a push:
instead of IEnumerable<String> Errors() (pull errors)
we push the errors in a handler
DoWithErrors(Action<IEnumerable<String>> errorHandler) -> Some will call the the action, None will do not

so we could use it like this:

Option<T> maybe = factory.TryCreate(args);

if (maybe.HasValue()) { ... do something with it }
else {
maybe.doWithErrors(View.DisplayErrors);
}

It is not difficult to associate an extra validation action for each arg/candidate field.

We just add optional args to TryCreate(args, params IAction[] actions) which we'll define as
mapping arg1 -> action1, arg2 -> action2. (if we have more args then actions, we don't call any action for them)

eg.

Option<Address> maybe = addressFactory.TryCreate(street_candidate, number_candidate, city_name_candidate, view.SignalErrorStreetName, view.SignalErrorValidateNumberCandidate, view.SignalValidateCityName)

...probably this will evolve to a 'framework', but at least a safe-type one, not string/reflection-based... And probably the annotation/reflection based are more AOP/crosscutting then this will be.

Thursday, March 27, 2008

I don't get Spring

Like CrazyBob, of guice fame, I also don't get Spring. Hammet also doesn't get it.
I mean what is the whole idea of wiring by xml? To decouple the wiring from the model.
But if you put the wiring.xml in the jar, so that it lands in the maven repository, to be used by others then it's not really decoupled.

Suppose I have 2 services, with their corresponding interfaces

class Producer implements IProducer { ... }

class Consumer implements IConsumer {
____Consumer(IProducer producer) { ... }
____...
}

what do we put in the xml file ? Basically we repeat the code-lines.
[bean id="..." class="Producer][/bean]
[bean id="..." class="Consumer"]
____[constructor-arg ref="..." index="0"/]
[/bean]

So not only we write again the required dependency, but we do it in xml so that we don't get
the benefit of refactoring (any changes due to renaming are lost).
I've intentionally left the ids unspecified. What should we put in there? The name of the class or the name of the interface?
- If we put the name of the class, then the Consumer-owner must know which class implements the IProducer interface, so a large part of the benefit of using interfaces is lost.
- If we put the name of the interface, in a declarative way, 'I am an IConsumer and I need an IProducer' then we have really duplicated the constructor line and the class declaration line in XML.

And now what about setter-injection. When I look at a class, I look at the interface it implements and what services it needs (in the constructor) to fulfill that contract. But Spring favors 'Setter Injection'.

Wednesday, March 26, 2008

blog marketing

I've received a link about how-to make my blog more popular. (thanks Andi ;)
There are good tips in there but I'm not sure I want to go aggressive in 'active marketing':
  • it is more important that my readers say 'hey this is a cool guy with a good blog' that I say 'I am the greatest'
  • more time on marketing means less time on something else (this is probably weak, since I'm not a very effective blogger, but I compensate that by being an avid reader)
  • I would prioritize 'more, better content' higher than 'more aggressive marketing'. (I should really write more)
  • On the other side is really important to reach people and bring them something. An architect said that the real important think to do is to spread knowledge. Know imagine: instead of sitting here and doing a bad copy of bile-blog, without being even funny, winning about how java is crap, C# is crap, (btw. C# is better than java, sic!), I could/should put some interesting stuff in here and move at least a hand of developers to a better programming world. So if I can reach/teach at least 3 people, and every 'student' will reach at most 3 people and so on, maybe we can reach the critical mass, and move something.... (...or maybe this was just a naive rant)
Making it short: help me make the blog more popular: reddit, technorati, dzone me.

Tuesday, March 18, 2008

Memoization in Java

OnJava in 2003, Tim White gave us generic way to build a memoize in java.
IMHO, Mr. White is trying to use big guns (dynamic proxy, reflection) on a small problem: function composition.

If we use/declare an interface:
public interface IFunc1 {
____R apply(A1 arg1);
}

then we can do implement Memoize1 (on 1 argument) as: (I use the Scala notation for generics [,] since blogger cuts out the xml devil quotes \<,\>)

public class Memoize1[A1, R] implements IFunc1[A1, R] {
____private final IFunc1[A1, R] func;
____private final Map[A1, R] cache;

____public Memoize1(IFunc1[A1, R] func) {
________this(func,new HashMap[A1, R]());
____}

____public Memoize1(IFunc1 func, Map[A1,R] cache) {
________this.func = func;
________this.cache = cache;
}

public R apply(A1 arg1) {
____R result = cache.get(arg1);
____if (result == null) {
________result = func.apply(arg1);
____cache.put(arg1, result);
____}
____return result;
____}
}

That's it. Generic. Composable. Reusable. No schnick-schnack.
Similar memoizer could be provide for IFunc2, IFunc3...
Notice that the Memoize has the same signature as the function it encapsulates.

ps. here is the F# version.