Friday, 16 May 2014

Clojure practice - 2

After finishing the previous post I noticed that Kaloz's solution was a bit more concise, not leaning on a helper function. So here is a "more compact" version, even puttin the number->characters mapping definition in the same expression.

(defn compact-combinations [number]
  (let [num->chars { \2  "ABC" \3  "DEF" \4  "GHI" \5  "JKL" 
                    \6  "MNO" \7  "PQRS" \8  "TUV" \9  "WXYZ"}
        red-fn (fn [acc d]
                 (m/match (num->chars d)
                   nil acc
                   chs (for [c chs
                             i acc]
                           (str i c))))] 
    (reduce red-fn [""] number)))

(println (compact-combinations "34"))


or, purely for the sake of example, having even the println in it

(let [combinations (fn [number] 
                     (let [num->chars {\2  "ABC" \3  "DEF" \4  "GHI" \5  "JKL" 
                                       \6  "MNO" \7  "PQRS" \8  "TUV" \9  "WXYZ"}
                           red-fn (fn [acc d]
                                    (m/match (num->chars d)
                                      nil acc
                                      chs (for [c chs
                                                i acc]
                                              (str i c))))] 
                       (reduce red-fn [""] number)))]
  (println (combinations "514")))

Thursday, 15 May 2014

Clojure practice

Recently I have dabbled into Clojure. I've been planning a post for a while, but since now Kaloz has posted a Scala functional programming demonstration, the time has come to reply in kind. Please, read his post to get the problem, here I take the lazy way and simply show a Clojure solution.

(ns clojure-study.garbage
  (:require [clojure.core.match :as m]))

(def num->chars { 
                  \2  "ABC"
                  \3  "DEF"
                  \4  "GHI"
                  \5  "JKL"
                  \6  "MNO"
                  \7  "PQRS"
                  \8  "TUV"
                  \9  "WXYZ"})

(defn- red-fn [resolvedStrings number]
  (m/match (num->chars number)
    nil resolvedStrings
    item (for [c item
               i resolvedStrings]
            (str i c))))

(defn combinations [number]
  (reduce red-fn [""] number))

(println (combinations "77501998489"))

Thursday, 1 May 2014

DDD reference project

I haven't posted in a while, but wasn't completely idle. I'd like to improve our way of doing DDD in the team I'm working in, so I have endeavoured to create a reference DDD project, where good practices, distilled experiences and some new ideas are demonstrated. The result is here, general explanatory notes on the wiki. It was quite a task, but a rewarding one.

Wednesday, 26 February 2014

Defining your own exception types

I'm in a habit of creating different classes for different exceptions, as opposed to for example using RuntimeException-s or IllegalStateException-s describing details as a string in the constructor. I'm not hundred percent sure that's an ultimately better practice and recently I've watched a talk where the speaker adviced against class proliferation. True, in a language like Java, creating classes is very boilerplate. In Scala an exception class is probably half a line of code, and you can stuff a dozen in the same source file.
But, yesterday I realized there is a situation where a custom exception class comes handy. Imagine you put some validation logic in your domain class.
public class PlayerId {
    private final String id;
    public PlayerId(String id) {
        Validate.notNull(id); 
        this.id = id;
    }
}

The Validate can be a validator class from Apache Commons or some custom class you wrote throwing IllegalArgumentException-s. At the project I'm working on right now we are using messaging and ActiveMQ as the integration solution. If there is an exception, the message is bounced back to the queue and the broker retries to deliver it a couple of times before it gives up and puts the message in the Dead Letter Queue. So if the message had a null as a player id, no matter how many times the broker retries it will always fail, but in the meantime the process consumes time and threads, possibly generating the same error log for a number of times. Instead of this if you create a( possibly abstract) n custom exception for domain problems, like

public abstract class DomainException extends RuntimeException {
    public DomainException(String msg) {
        super(msg);
    }
}

And at the entry point of your system you do a try-catch for it
try {
     // do the real thing
} catch(DomainException ex) {
    //do something, e.g. logging
}

Then you can catch and handle the problems where there is no chance of recovery in retrying.

Tuesday, 25 February 2014

JPrinciple


Finally, I've finished porting the code to Scala + made a wikipage on Github. By the way, Github is awesome.
So the source code: https://github.com/matemagyari/principle
And the Wiki: https://github.com/matemagyari/principle/wiki/JPrinciple

Tuesday, 18 February 2014

DDD - Modules, Subdomains, Bounded Contexts

The exact meanings of these concepts have always eluded me, until yesterday I read some chapters from Implementing Domain-Driven Design, which has shed some light on the topic. I'd like to share some thoughts I think I've learnt.

Subdomains

Before going to discuss subdomains, let's talk about what Domain is in general. Domain is not something we build, but something that actually exists in the world. We only try to create a Model for it. Subdomains are also something existing independently of how they are modelled (if modelled at all). If we take Amazon as an example, users can browse the purchasable items, search for specific ones, have recommendations from Amazon, etc. This is a subdomain of the whole Amazon domain, we can call it Item Catalog subdomain for now. The user can also order items, view her previous order history, and manage her orders in some ways. This is the Order subdomain. These subdomains exist regardless of how Amazon implemented its application. Even if it's one monolithic ball of mud, using a single database table for everything, these subdomains are there. One purpose of DDD is to make them explicit and visible by a code base that reflects the structure of the Domain.

Bounded Contexts

As opposed to Subdomains, BCs are defined by the developers. A BC is where a ubiquitous language applies. Classes with the same name can mean different things in different BCs in the same domain. For example User in Item Catalog is someone with a browsing history, search patterns, recommendations. In the Order subdomain User is someone associated with orders and the ordering process. They are two different aspects of the same human being. But there is a one-to-one mapping between the two, probably manifesting in the same UserId.
Ideally, there is a one-to-one mapping between a Bounded Context and a Subdomain, so once the developers identified a subdomain, they design its own Bounded Context. Unfortunately in real world applications, where the boundaries of subdomains are not well recognised, BCs and Subdomains often overlap, a BC containing one or more Subdomains, or a single Subdomain is modelled with multiple BCs, or (in the messiest case) the overlap can be only partial.
I think a BC should be one deployable artifact (e.g. a jar or war file), but Vaughn mentions BCs implemented by multiple deployables, and I'm not sure whether packing multiple BCs in one component is a bad or good idea.

Modules

Modules in Java are simply packages. A Module can contain multiple aggregates if they are cohesive enough, or just one. Modules are really a less coarse-grained, lightweight versions of Bounded Contexts.


Saturday, 7 December 2013

Domain Services - representing external dependencies in the Domain

For the most of us who start learning DDD, Domain Services seem to be a strange beast at first. The general definitions says that logic that "falls between" entities should find its place in a Domain Service. Simple as it sounds, in concrete situations it can be difficult to decide where to put a piece of logic. In the entity or create a service? In this post I'd like to show a different, but very frequent use of domain services. This is the manifestation of external dependencies in the domain. Let's see an example for not being so abstract. Imagine we are developing a military application comprising multiple, distributed components. Our task is develop the component that receives an encrypted message from the enemy, decodes it, then sends the decrypted message to the headquarters. Physically there are 3 components in the system, one that processes the decrypted message (headquarters), one that actually does the decrypting, and our component in-between. They are communicating via web-services. Our domain could look like

interface EncryptedMessage  { ... }
interface DecryptedMessage  { ... }
// domain service representing the HeadQuarter component in the system
interface HeadQuarter {
   void send(DecryptedMessage decryptedMessage);
}
// domain service representing the CodeBreaker component in the system
interface CodeBreaker {
  DecryptedMessage breakIt(EncryptedMessage encryptedMessage);   
}
//the heart of our simple domain
class EnemyMessageCatcher {
  private HeadQuarter headQuarter;
  private CodeBreaker codeBreaker;
  void captureDecryptAndForward(EncryptedMessage encryptedMessage) {
    DecryptedMessage decryptedMessage = codeBreaker.breakIt(encryptedMessage);
    headquarter.send(decryptedMessage);
}
//infrastructure layer
class WSBasedHeadQuarter implements HeadQuarter { //calling some webservice }
class WSBasedCodeBreaker implements CodeBreaker { //calling some webservice }
}


Both the HeadQuarter and the CodeBreaker are domain services. Although our domain knows nothing about how these functionalities are implemented (whether they are in other physical components, or just in simple objects), it still knows about the concept, that there is a HeadQuarter who needs to be notified and there is a CodeBreaker that can decrypt the enemy's messages. That's why the interface(=concept) is in the Domain and the implementation(=the details) is in the infrastructure. Using Hexagonal Architecture-terminology, the domain service (interface) is the port, and the implementation is the adapter.
The DDD-savvy reader can notice, that the Repository pattern is actually an ordinary domain service. It represents the concept of storing and retrieving objects in the domain, and hides away how it's done exactly. I suppose the only reason for it being a separate pattern is simply that most application has to deal with persistence.