Working with domain services

Working with domain services

When modeling a problem domain, we'll certainly face situations where the task at hand does not fit adequately into any of the object categories that we've seen so far in the domain hexagon: entities, value objects, and aggregates. Earlier, we met a situation where we removed from the Router entity a method responsible for retrieving a list of routers. That method seemed to be in the wrong place because, in our topology and network inventory scenario, a router usually doesn't list other routers. To deal with this cumbersome situation, we've refactored the router list method in a separate object. Eric Evans calls such objects domain services.

I believe it's important to distinguish domain services from any other type of service. For example, in Model-View-Controller (MVC) architectures, services are often seen as bridges that connect the different facets of an application, handling data and orchestrating calls within and outside the system. Their usage is often associated with software development frameworks such as Spring that even have a service annotation. But independent of the context, I believe the main difference between distinguished service types lies not in the meaning but in the scope.

What makes something a service? It's the ability to perform some worthwhile effort. This characteristic is inherent to any service, both in the real world and with computers. However, in the latter case, we should care about Separation of Concerns (SoC), modularization, decoupling, and other relevant matter for good architecture. It's based on those concerns that we nail down domain services to the realm of the Domain hexagon. They perform worthwhile tasks—as any other services—but within the constrained scope of our problem domain. This means domain services should not call services or other objects that operate in application or framework hexagons. Instead, objects from those hexagons are clients who call domain services.

In the previous section, we created the following two methods in our Router entity class, which is also the aggregate root:

public void addNetworkToSwitch(Network network){
	this.networkSwitch = networkSwitch.addNetwork(network);
}
public Network createNetwork(IP address, String name, long cidr){
	return new Network(address, name, cidr);
}        

In the following code snippet, we have a service class operating over those two Router entity methods:

public class NetworkOperation {

	final private int MINIMUM_ALLOWED_CIDR = 8;

	public void createNewNetwork(Router router, IP address, String name, int cidr) {
		if(cidr < MINIMUM_ALLOWED_CIDR) 
			throw new IllegalArgumentException("CIDR is below"+MINIMUM_ALLOWED_CIDR);
		if(isNetworkAvailable(router, address))
			throw new IllegalArgumentException("Address already exist");
		Network network = router.createNetwork(address,name,cidr);
		router.addNetworkToSwitch(network);
	}

	private boolean isNetworkAvailable(Router router, IP address){
		var availability = true;
		for (Network network : router.retrieveNetworks()) {
			if(network.getAddress().equals(address) && network.getCidr() == cidr)
				availability = false;
			break;
		}
		return availability;
	}
}        

We have a method called createNewNetwork that is responsible for creating a new network object and adding it to the switch linked to our router. We should meet two constraints to be able to create a network. The first, simple one checks if the minimum Classless Inter-Domain Routing (CIDR) has not been violated. The second constraint is somewhat more elaborate. It verifies whether the network address is already being used anywhere on the whole network.

With this approach, we're delegating to the NetworkOperation domain service class the responsibility to deal with tasks that don't fit quite well into entities or value objects. That's also a valuable effort to prevent entity and value object classes from growing too large with far more features than necessary according to the problem domain.

Until now, we've been dealing with invariants directly on entities, value objects, or service classes. Next, we'll see an approach to accommodate those invariants in a more orderly and organized way.

要查看或添加评论,请登录

samson baraka的更多文章

  • Assuring consistency with aggregates

    Assuring consistency with aggregates

    We've so far seen how valuable entities are to represent things in a problem domain. Also, we saw how value objects are…

  • Enhancing descriptiveness with value objects

    Enhancing descriptiveness with value objects

    Implementing Domain-Driven Design pointed out quite well that we should use value objects to measure, quantify, or…

  • Wrapping Business Rules inside Domain Hexagon

    Wrapping Business Rules inside Domain Hexagon

    Previously we learned about the Domain as the first hexagon in hexagonal architecture. By being the innermost hexagon…

  • Advantages of the hexagonal approach

    Advantages of the hexagonal approach

    If you're looking for a pattern to help you standardize the way software is developed at your company or even in…

  • Framework hexagon

    Framework hexagon

    Things seem well organized with our critical business rules constrained to the Domain hexagon, followed by the…

    1 条评论
  • Application hexagon

    Application hexagon

    So far, we've been discussing how the Domain hexagon encapsulates business rules with entities and value objects. But…

  • Understanding the hexagonal architecture 2

    Understanding the hexagonal architecture 2

    In the last episode we introduced the domain hexagon. Now, let's talk about the components that comprise this hexagon.

  • Understanding the hexagonal architecture

    Understanding the hexagonal architecture

    Create your application to work without either a UI or a database so that you can run automated regression tests…

  • Building a UI with SSE support

    Building a UI with SSE support

    In order to complete our use case we need an HTML page with some JavaScript code to communicate with the server. For…

  • Why Hexagonal Architecture?

    Why Hexagonal Architecture?

    Software that's not well organized and lacks sound software architecture principles may work just fine but develop…

社区洞察

其他会员也浏览了