Tuesday 31 March 2015

Improving existing code - imaginary checklist - 2

Continuing the completely random and unprioritized checklist. Some of them are easy to fix, some are heavy.

Eliminate mutable state where possible

Immutability has many advantages over mutable objects, none of them will I mention here. For an example see the Query class in the previous post. Avoid setters, use final keyword and defensive copies.

Thread safety

Quite self-explanatory.

Separation of concurrency and domain logic

Multi-threading logic should be separated from the rest of the code. It's quite complex on its own, even more when is intertwined with other things.

Invariants and UnitOfWork-s

Check what are the units of work, and what are the invariants. The formers should encapsulate the latter. This is quite an important point. And a not so low hanging fruit, probably.

Push third-party code to the outer layers

This might be a big one. Practically I think almost all application should follow the Hexagonal Architecture style. This can be achieved iteratively, but could take a long time to get there if the code hasn't been written that way.

To be continued...

Binary Tree implementation in Haskell, Clojure and Scala - 2

And thanks to @Kaloz, here is the Scala implementation with a slightly altered/extended functionality.

Improving existing code - imaginary checklist - 1

I endeavour to prepare a checklist I would go through if I had to start to work on a brownfield project. Small things to improve, hunt for the low hanging fruits. Don't expect any enlightenment here, these are just pearls of blue-collar wisdom.

Handling unrecoverable exceptions

In my current project we use messaging via ActiveMQ. Should an exception occur, the message is bounced back to the queue, then retried. It's fine, as long as there is a chance of recovery and sometimes - for example when the message is invalid in some way - there is none. In this case bouncing the message back is a waste of time and resource, plus the message can and up in the Dead Letter Queue leading to memory loss. So instead we should catch these exceptions as close to the entry point as possible and simply log them.

Validating input

Related to the previous point. To adhere the fail-fast principle, the inputs of the system should be validated. Validation is usually against some domain criteria, so I would put the logic in the Domain layer, just as the input passed the ACL. Should the input fail to comply, throw an unrecoverable exception.

Validate domain objects

I wouldn't stop at the inputs. I'd validate every domain object upon creation. Design by contract is a very good practice.

The validation should throw an unrecoverable exception. See the first point.

To be continued...

Tuesday 24 March 2015

Binary Tree implementation in Haskell, Clojure and Scala

I've embarked on learning Haskell recently. I only start to suspect the power of this language, but I'm already impressed with its beautifully succinct and readable, no-nonsense syntax. Nuff' said, let's do a demonstration!

Haskell


Clojure


Scala - I've failed with this one. Maybe @Kaloz can help me out.