Repository pattern and/or/vs business logic layer

前端 未结 2 879
星月不相逢
星月不相逢 2021-01-31 17:02

I have a problem I want to know your opinion.

I am trying to use Repository Pattern. I have a repository object which load data to a POCO. I have also created a Business

2条回答
  •  忘掉有多难
    2021-01-31 17:34

    There are two basic ways to think about business rules when designing your domain.

    1.) The domain entities are basic POCO/DTOs. And you hand them off to domain services. These services could be as simple as another class, or they really could be actual services sitting on another server.

    var user = repository.Find(x => x.UserName == userName);
    if (userLogonService.IsValidUser(user, password)) {
       userLogonService.UpdateUserAsLoggedOn(user);
    }
    repository.SaveChanges();
    

    2.) The domain entities contain their own operation logic. This is closer to what many MVC patterns will follow. And since you asked, this is the model that I prefer.

    var user = repository.Find(x => x.UserName == userName);
    if (user.CheckPassword(password)) {
        user.LogOnNow();
    }
    repository.SaveChanges();
    

    Both are completely valid patterns. #1 has a discrete business operation tier, but suffers from an Anemic Domain Model. #2 can lead to big domain entities if you domain starts to become complicated, or if a model can do a lot of things.

    EDIT #1: Response to John Kraft

    Oven.Bake(myPizza) vs. myPizza.Bake()

    I mostly agree. Do you have a single Oven service, or do you have dozens of available ovens stored in an oven repository where oven is just another domain entity? In #2, the oven is part of the domain. The way I tend to do domain modeling, most nouns are domain entities, unless you are 100% sure that there is exactly one of the thing.

    But something does happen to pizza when it is baked.

    interface ICanBeBaked {
        int BakeMinutes { get; }
        int BakeTemp { get; }
        void Bake();
    }
    class Pizza : ICanBeBaked {
        int BakeMinutes { get { return 15; } }
        int BakeTemp { get { return 425; } }
        void Bake() {
            // melt cheese!
            this.isBaked = true;
        }
    }
    class Oven {
        void Bake(ICanBeBaked thingToBake) {
            // set the temp, reserve this oven for the duration, etc.
            thingToBake.Bake();
        }
    }
    

提交回复
热议问题