Stop Trying to turn Everything into a Service — Organize your Monolith First

Here is an example of an interface that calculates the tax rate on an order.

// iTaxCalculator.php
include ValueObjectAddress;
include ValueObjectTaxRate;
interface iTaxCalculator
{
/**
* @throws InvalidArgumentError
* @return bool
*/
public function setTaxNexus(array $addresses);
 /**
* @return bool
*/
public function setDestination(Address $address);
 /**
* @return bool
*/
public function setShippingOrigin(Address $address);
 /**
* @return ValueObjectTaxRate
*/
public function getTaxRate();
}

Just by looking at this interface, we can infer a lot about how it works without even looking at the code. It uses a destination address, a shipping origin, and a store’s tax nexus to get a tax rate for an order. Even in a monolithic codebase, this practice of hiding all of the details behind a single interface is a good habit to get into.

Step 3— Use immutable Value Objects

Many popular programming languages today, including the two I use primarily, PHP and JavaScript, make it very easy to pass around random containers of information as associative arrays or objects. The nature of a breaking up our codebase entails that a lot of data will be flowing around through our various new components. And while passing around plain old objects can work, it would be nice if there were some kind of contract stating exactly what is coming into each subdomain area and what is going to be coming back out of it. It would also be nice if these objects were immutable and could only be altered if a setter is explicitly defined.

This is where value objects come in. Value objects are not model instances and they do not have an ID. They are immutable containers of information with defined properties and their state is entirely dependent upon its values. Here is an example:

//TaxRate.php
class TaxRate
{
/**
* @var float
*/
private $tax_rate;
   /**
* @var string add|base|instead
*/
private $rate_type;
    public function __construct($tax_rate, $rate_type)
{
$this->tax_rate = $tax_rate;
$this->rate_type = $rate_type;
}
   /**
* Get the tax rate
*/
public function getTaxRate()
{
return $this->tax_rate;
}
   /**
* Get tax type
*/
public function getTaxType()
{
return $this->tax_type;
}
}

It may, at first, seem tedious and unnecessary to do this, but it gives us the confidence that in a system that operates on tax rates, we will always be working with tax rates and not random blobs of values that may or may not have the fields we need.

Summary

Going from a monolith code to a SOA is a daunting task, and it’s impossible to do it in one step. If you find yourself in a position in which your codebase has become too large to quickly iterate on, do not immediately start trying to hack it up. Instead, make it your goal to organize your monolith into well-defined subdomains using the DDD concepts described in this post. Once that is done, it will be much easier to start breaking out code as individual services.

read original article here