Repository pattern and/or/vs business logic layer

前端 未结 2 832
星月不相逢
星月不相逢 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();
        }
    }
    
    0 讨论(0)
  • 2021-01-31 17:44

    My "DAL" (more of a home-grown ORM, which is another topic) is really a couple of layers in itself; one abstraction that provides repository and some active record pattern support, and below that is the actual data access code.

    We have a minimal business layer at this point, but the real reason is that it's thin is that there's way too much (legacy) business logic embedded in web page code-behinds. As that gets refactored, I expect the business layer to grow and grow and grow.

    This is fairly standard layering. You don't say why you're unhappy with your current stack, but keep in mind that the core reason for doing this is separation of responsibilities. You might also want to take a look at concepts of Domain Driven Design; it provides lots of food for thought for organizing code around business policies and practices, rather than specifically software issues. It's a very useful analytical tool to have in your toolbox.

    0 讨论(0)
提交回复
热议问题