Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Add Business Logic to the Domain Service in Domain-Driven-Design?

in my project ,the Business Logic all in the Application Service,Domain Service just some entity,who can tell me or give me a example to show How to Add Business Logic to the Domain Service in Domain-Driven-Design? very thanks!

UPDATE

i write a simple solutation,this solutation is a vote system,the solutation main part is:

enter image description here

Vote.Application.Service.VoteService.cs:

namespace Vote.Application.Service
{
    public class VoteService
    {
        private IVoteRepository _voteRepository;
        private IArticleRepository _articleRepository;

        public VoteService(IVoteRepository voteRepository,IArticleRepository articleRepository)
        {
            _voteRepository = voteRepository;
            _articleRepository = articleRepository;
        }

        public bool AddVote(int articleId, string ip)
        {
            var article = _articleRepository.Single(articleId);
            if (article == null)
            {
                throw new Exception("this article not exist!");
            }
            else
            {
                article.VoteCount++;
            }

            if (IsRepeat(ip, articleId))
                return false;

            if (IsOvertakeTodayVoteCountLimit(ip))
                return false;

            _voteRepository.Add(new VoteRecord()
            {
                ArticleID = articleId,
                IP = ip,
                VoteTime = DateTime.Now
            });

            try
            {
                _voteRepository.UnitOfWork.Commit();
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private bool IsRepeat(string ip, int articleId)
        {
            //An IP per article up to cast 1 votes
            //todo
            return false;
        }

        private bool IsOvertakeTodayVoteCountLimit(string ip)
        {
            //An IP per day up to cast 10 votes
            //todo
            return false;
        }
    }
}

Vote.Domain.Contract.IVoteRepository.cs:

namespace Vote.Domain.Contract
{
    public interface IVoteRepository
        : IRepository<VoteRecord>
    {
        void Add(VoteRecord model);
    }
}

Vote.Domain.Contract.IArticleRepository.cs:

namespace Vote.Domain.Contract
{
    public interface IArticleRepository
        : IRepository<Article>
    {
        void Add(VoteRecord model);

        Article Single(int articleId);
    }
}

Vote.Domain.Entities.VoteRecord:

namespace Vote.Domain.Entities
{
    public class VoteRecord
    {
        public int ID { get; set; }

        public DateTime VoteTime { get; set; }

        public int ArticleID { get; set; }

        public string IP { get; set; }
    }
}

Vote.Domain.Entities.Article:

namespace Vote.Domain.Entities
{
    public class Article
    {
        public int ID { get; set; }

        public string Title { get; set; }

        public string Content { get; set; }

        public int VoteCount { get; set; }
    }
}

i want move the Business Login in application.service to Domain.service(current not this project),who can help me?how to do is reasonable? very thanks!

like image 715
artwl Avatar asked Aug 16 '12 05:08

artwl


People also ask

Where does business logic go in DDD?

This is the simplest scenario. If your domain model is very simple (i.e. CRUD based), then putting the business logic directly in a transaction script or a request handler might be ok.

Does business logic go in domain layer?

The domain layer is responsible for encapsulating complex business logic, or simple business logic that is reused by multiple ViewModels. This layer is optional because not all apps will have these requirements. You should only use it when needed-for example, to handle complexity or favor reusability.

What is domain logic DDD?

Domain-driven design (DDD) is a major software design approach, focusing on modelling software to match a domain according to input from that domain's experts. Under domain-driven design, the structure and language of software code (class names, class methods, class variables) should match the business domain.

What is business domain in microservices?

A domain model contains clusters of different data entities and processes that can control a significant area of functionality, such as order fulfillment or inventory. A more fine-grained DDD unit is the aggregate, which describes a cluster or group of entities and behaviors that can be treated as a cohesive unit.


2 Answers

DDD is focusing how to design domain models to fit with requirement, the schema in database does not matter much.

If your domain entity is just property bag, seems you are violating the Anemic Model anti-pattern. Business logic should be in domain entities. So, in your case, in order to avoid business logic leaking to Application service. You can have a new model called Client for example to store Ip or other properties if necessary.

To have easier understanding, whether Client exceeds the limits in day, this method should be in Client class. Similar with the method IsRepeated.

So, your domain object should be:

public class Client
{
    public string Ip { get; set; }
    // More properties if needed

    public List<Vote> Votes { get; set; }

    public bool ExceedLimitInDay()
    {
    }
}

public class Vote
{ 
    public int Id { get; set; } 
    public DateTime VoteTime { get; set; } 
    public Article Article { get; set; } 
    public Client { get; set; } 
}

public class Article   
{   
    public int Id { get; set; }   
    public string Title { get; set; }   
    public string Content { get; set; }   

    public List<Vote> Votes { get; set; }

    public bool IsRepeated(string ip)
    {
        return Votes.Select(v => v.Client.Ip == ip).Any();      
    }
} 

Note: If you don't need to create new table Client, just map it into Vote table. As for VoteCount properties, it is needless because you can count based on the list of Vote

like image 153
cuongle Avatar answered Oct 24 '22 09:10

cuongle


I think Vote and Article are an Aggregate. I don't know much about your domain, but I assume each vote is only important to a given Article. Votes won't be shared across Articles so they should be treated as members of the aggregation, and not treated as entities of the whole domain.

In my opinion, Article would be the root entity of the Aggregate and Vote would be a member entity inside. Applying this "pattern" you could encapsulate all the business logic inside.

You could have a AddVote(...) inside your article, or some business logic like this.

Then you might be wondering.. "Ok.. but what about persistance??". Since you are defining your Article-Vote as an Aggregate, you then would treat them together. If you perform CRUD operations to an Article, at the same time you will be performing these operations in their Aggregate members (votes). So you might need a repository for the ArticleAggregate, it will take care of article's votes.

Hope this make sense to you. Choose the best option depending on your domain.

like image 43
margabit Avatar answered Oct 24 '22 08:10

margabit