是否有任何好的模式/原则来分离创建和更新逻辑

发布于 2024-10-30 22:47:40 字数 223 浏览 1 评论 0原文

以用户的简单示例为例,根据我的经验,我发现根据您是创建还是更新用户,执行的检查/逻辑总是略有不同(此问题也扩展到更新其他域实体) 。当您添加自由的洒水和基本原理时,代码很快就会变得像意大利面条一样 “只需在更新用户时对用户进行此检查”和“哦,只需在创建用户时执行此检查,逻辑,插入”

所有这些的总和就是一个庞大的代码庞然大物,看起来非常碍眼。我想完全重构/分离这个逻辑只是常识。或者我疯了。

谢谢,

Taking the simple example of a user, in my experience, I have found that there is always a slightly different piece of checking/logic to perform depending on whether you are creating or updating a user (this problem extends to updating other domain entities too). The code quickly gets spaghetti-fied when you add liberal sprinkilings with rationale such as
"Just do this check for the user when updating them" and "ooh just do this check, logic, insert when creating the user"

The sum of all this is a monolithic behemoth of code which is a bloody eyesore to look at. I suppose its just common-sense to refactor/separate out this logic completely. Or am I mad.

Thanks,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

渡你暖光 2024-11-06 22:47:41

对于这种情况,我会使用 模板模式。基本上,您可以将所有重复代码放入基类中,并让继承的类实现具体细节。一个简单的伪代码示例如下所示:

IRep

class IRep
{
   void Add(object a);
   void Remove(object a);
}

BaseRep

abstract class BaseRep : IRep
{
    void Add(object a)
    {
       if(OkToAdd(a))
       {
          // Common Rep code here
       }
    }

    void Remove(object a)
    {
       if(OkToRemove(b))
       {
          // Common Rep code here
       }
    }

    abstract bool OkToAdd(object a);
    abstract bool OkToRemove(object a);
}

MyRep1

class MyRep1 : BaseRep
{
    bool OkToAdd(object a)
    {
       // Add specific checks here for MyRep1
    }

    bool OkToRemove(object a)
    {
       // Add specific checks here for MyRep1
    }
}

MyRep2

class MyRep2 : BaseRep
{
    bool OkToAdd(object a)
    {
       // Add specific checks here for MyRep2
    }

    bool OkToRemove(object a)
    {
       // Add specific checks here for MyRep2
    }
}

I would use the Template Pattern for this situation. Basically, you can put all the duplicate code in the base class and have the inherited classes implement the specifics. A simple psuedo code example would look like this:

IRep

class IRep
{
   void Add(object a);
   void Remove(object a);
}

BaseRep

abstract class BaseRep : IRep
{
    void Add(object a)
    {
       if(OkToAdd(a))
       {
          // Common Rep code here
       }
    }

    void Remove(object a)
    {
       if(OkToRemove(b))
       {
          // Common Rep code here
       }
    }

    abstract bool OkToAdd(object a);
    abstract bool OkToRemove(object a);
}

MyRep1

class MyRep1 : BaseRep
{
    bool OkToAdd(object a)
    {
       // Add specific checks here for MyRep1
    }

    bool OkToRemove(object a)
    {
       // Add specific checks here for MyRep1
    }
}

MyRep2

class MyRep2 : BaseRep
{
    bool OkToAdd(object a)
    {
       // Add specific checks here for MyRep2
    }

    bool OkToRemove(object a)
    {
       // Add specific checks here for MyRep2
    }
}
夜血缘 2024-11-06 22:47:41

我喜欢把它们完全分开。尽管这可能看起来像是代码重复,但它允许将来独立地发展这些操作。它们彼此之间可能会有很大不同:在创建时,可能有一些字段不是必需的,甚至不允许设置,并且每种情况下可能有很多不同的规则需要检查。如果你完全分开这些动作,那么你就有完全的自由来发展它们。

I like to have them completely separated. Even though this may look as code duplication, it allows to evolve these actions independently in the future. And they can get quite different from each other: when creating, there may be some fields not required, or even not allowed to be set, and there may be lots of different rules to be checked in each case. If you completely separate these actions, then you have complete freedom how to evolve them.

给不了的爱 2024-11-06 22:47:41

我发现总有一个
略有不同的一块
检查/逻辑执行取决于
无论您是创建还是更新
用户

当然涉及不同的逻辑。

创建实体和更改实体是两种截然不同的操作。不要试图让它们执行相同的操作。

I have found that there is always a
slightly different piece of
checking/logic to perform depending on
whether you are creating or updating a
user

Of course there is different logic involved.

Creating an entity and making a change to an entity are two distinctly different operations. Don't try to make them the same operation.

情场扛把子 2024-11-06 22:47:41

好吧,我的职业生涯又过去了几年,现在我已经了解了设计/理解软件时的多种方法。

我所描述的似乎是领域模型和事务脚本贫乏的症状。如果硬塞进存储库或针对持久性存储的创建/更新插入/更新操作,则埋藏在用于持久性的方法/操作中的业务规则很快就会变得混乱。

在这种方法中,意图和业务规则很快就会丢失。

缓解这种情况的一种方法是依靠 DDD 方法并仔细建模行为,以便仅更改相关状态,然后保留(最有可能在该聚合中的聚合或实体/值对象上)。这有助于通过明确指示正在更改的状态的操作来确保存在可审计的故事。例如:

Customer.AddUsername(string username)

此方法将更新用户名,并在操作中发挥业务规则的范围。

Ok, so I'm a few years further on in my career and I now have an awareness of a number of approaches when designing/understanding software.

It seems what I was describing seems symptomatic of an anaemic domain model and transaction script. Where the business rules buried in the method/operation used for persistance quickly becomes tangled if shoe-horned into a create/upsert/update operation on a repository or against a persistence store.

Intent and business rules are quickly lost in this kind of approach.

A way to alleviate this is to lean on a DDD approach and carefully model behaviour so that only relevant state is changed and then persisted (most likely on an aggregate or entity/value object in that aggregate). This helps ensure that there is an auditable story by virtue of an operation explicitly indicating what state is being changed. For example:

Customer.AddUsername(string username)

Where this method would update the username, with scope to have business rules in play within the operation.

杀手六號 2024-11-06 22:47:40

嗯,基本上有两种模式可供选择:

  1. 为添加和更新创建完全独立的案例。
  2. 创建一个处理添加和更新的单个案例。

具有单独案例的优点是代码变得更清晰,缺点是您重复了大部分代码。使用单一案例来避免重复代码也意味着代码变得更加复杂。

尝试创建介于两者之间的东西很可能最终会带来两种模式的缺点。

Well, there basically is two patterns to choose from:

  1. Make completely separate cases for adding and updating.
  2. Make a single case that handles both adding and updating.

The advantage of having separate cases is that the code gets cleaner, the drawback is that you are repeating most of the code. Using a single case to avoid repeating the code also means that the code gets more complex.

Trying to create something that is in-between will most likely end up with the drawbacks of both patterns.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文