Application services

In our application core, we will need to create two application services, TeamService and BoardService, to provide the abilities that Controller requires. As mentioned earlier, application services need to be kept as thin as possible; they should try not to involve any business logic because business logic should be kept inside domain models and domain services.

The following is the implementation of com.taskagile.domain.application.TeamService:

@Service
@Transactional
public class TeamServiceImpl implements TeamService {
...
@Override
public List<Team> findTeamsByUserId(UserId userId) {
return teamRepository.findTeamsByUserId(userId);
}

@Override
public Team createTeam(CreateTeamCommand command) {
Team team = Team.create(command.getName(), command.getUserId());
teamRepository.save(team);
domainEventPublisher.publish(new TeamCreatedEvent(this, team));
return team;
}
}

As you can see, the findTeamsByUserId() method is quite straightforward, and the createTeam() method takes one parameter, CreateTeamCommand. It keeps all of the necessary information the Team.create() factory method requires to create a new team, and we only use this command inside the application service. We do not use it in our domain models or domain services because CreateTeamCommand is part of the API contract of the application service and it might be changed in the future. We certainly do not want a change to CreateTeamCommand to impact our domains. Application services should depend on domains and not the other way around.

The following is the implementation of com.taskagile.domain.application.BoardService:

@Service
@Transactional
public class BoardServiceImpl implements BoardService {
...
@Override
public List<Board> findBoardsByMembership(UserId userId) {
return boardRepository.findBoardsByMembership(userId);
}

@Override
public Board createBoard(CreateBoardCommand command) {
Board board = boardManagement.createBoard(
command.getUserId(), command.getName(),
command.getDescription(), command.getTeamId());
domainEventPublisher.publish(new BoardCreatedEvent(this, board));
return board;
}
}

As you can see, in the createBoard() method of BoardServiceImpl, we call the createBoard() method of BoardManagement, which encapsulates the business logic of creating a board. That's something the application service does not need to know.

The following is how com.taskagile.domain.model.board.BoardManagement looks:

@Component
public class BoardManagement {
...
public Board createBoard(UserId creatorId, String name, String
description, TeamId teamId) {
Board board = Board.create(creatorId, name,
description, teamId);
boardRepository.save(board);
// Add the creator to as a board member
BoardMember boardMember = BoardMember.create(board.getId(),
creatorId);
boardMemberRepository.save(boardMember);
return board;
}
}

As you can see, in its createBoard() method, we use the Board.create() factory method to create a board and then save it to a repository. After that, we create an instance of BoardMember and save it into its repository as well. As you saw earlier, the BoardMember model is quite simple. It only has boardId and userId properties. In a future version of TaskAgile, we can add properties such as a joinedDate field to keep the date and time when a user joined a board and a permissions field to indicate what a member can do inside that board, as well as a memberType field to differentiate between a guest member who is a client or a partner. Given the limited scope of the first version of TaskAgile, we will only keep boardId and userId in it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.101.81