当前位置: 首页 > 知识库问答 >
问题:

在清洁架构中设计实体的最佳实践是什么?

施兴言
2023-03-14

我试图使用Kotlin实现干净的架构。这一过程的流程将是:

usecase-->从DB获取rowresult-->将rowresult映射到实体-->usecase用于检查业务规则的实体

代码示例:

UserTable
------------------
id (varchar)
email (varchar)
password (varchar)
gender (varchar)
phone (varchar)
anotherAttribute1
anotherAttribute2
.
anotherAttributeN
class UserEntity {
    val id: String,
    val email: String,
    val password: String,
    //Business rules
    fun isUserAllowedToLogin(): Boolean {
        //validate password
    }
}

interface UserDataStore {
    fun getUser(email: String): User
}

class UserDataStoreImplementation {
    fun getUser(email: String): User {
        //query to DB
        val resultRow = db.query("SELECT id, email, password from UserTable where email=${email}")
        //map to UserEntity
        val user: UserEntity = Mapper.toUserEntity(userResultRow)
        return user
    }
}

class LoginUseCase {
    fun execute(emailInput: String, passwordInput: String): Boolean {
        val user = UserDataStore().getUser(emailInput)
        if (!user.isUserAllowedToLogin) {
            //do something
        }
        return result
    }
}
class UserEntity {
    val id: String,
    val email: String,
    val password: String,
    val gender: String,
    val phone: String,
    //more attributes
    .
    .
    //more complex object
    val Staff: Staff
    fun isUserAllowedToLogin(): Boolean {
        //validate password
    }
    fun checkStaffStatus(): Boolean {
        //do something
    }
}

class UserDataStoreImplementation {
    fun getUser(email: String): User {
        //query from DB which will have a lot of attributes
        val resultRow = db.query("SELECT * from UserTable where email=${email}")
        //map to UserEntity
        val user: UserEntity = Mapper.toUserEntity(userResultRow)
    }
}

共有1个答案

宋望
2023-03-14

问题1。假设我有另一个UseCase(GetUserFullDetailAndStaffDetail UseCase)将使用更复杂的用户属性,我是否应该为GetUserFullDetailAndStaffDetail UseCase使用相同的UserEntity?

实体是域对象,LoginUserUserDetail不同。我们经常认为只有一个用户。但是用户有不同的视角。你可以把它们看作是一种角色。

public class LoginUser {
  private String name;
  private String email;

  // ...
}

DetailUser

public class DetailUser {
  private String name;
  private String email;
  private String phone; 
  private String gender;
  // ...
}

这并不违反干燥原则,因为你不重复自己。我同意我们必须消除重复的代码,但是LoginUserDetailUser会因为不同的原因而改变。因此它们不会重复。这就是唯一的责任。

它们看起来相似,但相似只是重复的暗示。你得问自己更多的问题,看看它们是否真的是重复的。让我们考虑一下对登录用例的更改。也许只应该显示名字。那么这两个实体将只有一个共同的属性--名称。他们在commen中必须有多少属性才能复制?

如果在实体中实现业务逻辑,您将意识到有些方法只能在两个用例中的一个中调用,并且这些方法只使用属性的子集。然后你会看到这两个实体是不同的。

如果您只对所有用例使用一个存储库接口,您将很快意识到它将不断增长,直到包含数十个方法。最后,这一个界面将变得混乱。有些方法相似,但不同,你会试图找到疯狂的名字来区分他们。

public interface UserRepository {
 
   public User findSimpleUser();

   public User findAllUserInfo();

   public User findAllUserInfoForOrderProcess();

   // ... maybe dozens more
}

实现类将很大。也许很多方法是通过私有实用程序方法耦合的,因此对该共享代码的更改会影响其他用例,等等。

将接口分开是个好主意。也许您从不同的接口开始,但只有一个实现来实现这两个接口。也许您想在以后情况变得更糟时分解实现。但是,您已经有了分离的接口,您不必改变您的用例。

 类似资料:
  • 本文向大家介绍设计微服务的最佳实践是什么?相关面试题,主要包含被问及设计微服务的最佳实践是什么?时的应答技巧和注意事项,需要的朋友参考一下 以下是设计微服务的最佳实践: 为每个微服务分开数据存储 将代码保持在类似的成熟度等级上 为每个微服务进行单独的构建 部署到容器中 将服务器视为无状态的

  • 我正在读clean architecture的书,我想把它应用到我写的一些软件中。在该软件中,和等实体扮演着非常重要的角色。出于这个原因,为了避免重复,跨代码共享这些实体是有意义的,但这也违反了清洁体系结构的规则。 在这种情况下,什么是正确的决定?我应该在中添加一个“shared/entities”文件夹吗? 我正在做的项目主要是在flutter编程,如果这对答案很重要的话。

  • 问题内容: 我刚开始学习Go,并通读现有代码以学习“其他人的做法”。在这种情况下,遍历使用go“工作区”,尤其是与项目依赖关系有关的地方。 在处理各种Go项目时,使用一个或多个Go工作区(即$ GOPATH的定义)的常见(或存在)最佳实践是什么?我应该期望有一个类似于我所有项目的中央代码存储库的Go工作区,还是在我处理这些项目时都明确将其分解并设置$ GOPATH(有点像python) virtu

  • 在我的过去,我已经实施了一些网页刮取项目--从小型到中型(大约100.000个刮取页面)不等。通常我的起点是一个索引页,它链接到几个页面,上面有我想刮的细节。最后大部分时间我的项目都起作用了。但是我总是觉得我可以改进工作流程(特别是关于减少我给被清除的网站造成的流量的挑战[和连接到那个主题:被禁止的风险:D])。 这就是为什么我想知道你的(最佳实践)web刮板设计方法(针对小型和中型项目)。 通常

  • 问题内容: 我将开始使用AngularJS进行客户端和Django进行服务器端项目。 使他们像最好的朋友一样工作的最佳实践是什么(静态文件,身份验证,部署等) 问题答案: 有多种方法可以从Django模板中为客户端模板提供支持,以实现有趣的优化。但是,鉴于Django和AngularJS的模板语言之间的相似之处,在这里几乎不值得付出任何努力。对于此类大多数项目,我会将AngularJS的静态服务与

  • 问题内容: 我正在构建一个基于expressjs的应用程序,我想在其中记录所有事件。我可以找到温斯顿,这似乎很酷。无论如何,我正在寻找一种方法将其连接到我的expressjs应用程序。 我还想要在应用程序内部登录。我的要求不是那么简单,所以我想将所有内容记录在我的应用程序中(不仅是请求)。 我目前的情况: server.js (我想在此级别记录http请求) 路线/something.js con