Java 实现不同存储策略的模式

Java 实现不同存储策略的模式,java,design-patterns,Java,Design Patterns,我将实现数据映射器模式,将数据存储在不同的存储器/数据库中 实现这个概念的最佳OOP模式是什么 例如,我有Usermodel类 public class User { private int id; private String name; private String surname; /* getters, setters and model-level business logic */ } 和适当的数据映射器类 public class UserMapper {

我将实现数据映射器模式,将数据存储在不同的存储器/数据库中

实现这个概念的最佳OOP模式是什么

例如,我有
User
model类

public class User 
{
  private int id;
  private String name;
  private String surname;

  /* getters, setters and model-level business logic  */
}
和适当的数据映射器类

public class UserMapper
{
  public User findById(int id)
  {
    // perform query to MySQL, Redis or another DB
  }

  /* other methods */
}
通过创建多个存储策略类,然后将它们注入DataMapper类,使用策略模式是否是一个好主意

 public class UserMySQLStorageStrategy extends UserStorageStrategy
 {
   public User findById(int id)
   {
     // perform query to MySQL
   }
 }

 public class UserRedisStorageStrategy extends UserStorageStrategy
 {
   public User findById(int id)
   {
     // perform query to Redis
   }
 }

public class UserMapper
{
  protected UserStorageStrategy _storageStrategy;

  public UserMapper(UserStorageStrategy storageStrategy)
  {
    this._storageStrategy = storageStrategy;
  }


  public User findById(int id)
  {
    return this._storageStrategy.findById(id);
  }

  /* other methods */
}

您的策略看起来非常像mapper类本身。相反,将映射器和用户对象设置为接口,然后由特定实现选择如何/在何处存储它们可能是有意义的。如果您的UserMapper类执行了许多与存储无关的操作,并且尽管存储不同,也不需要更改,那么策略方法是有意义的;但是,如果UserMapper类所做的只是存储,那么一个接口和多个实现就会更简单。

您的策略看起来非常像mapper类本身。相反,将映射器和用户对象设置为接口,然后由特定实现选择如何/在何处存储它们可能是有意义的。如果您的UserMapper类执行了许多与存储无关的操作,并且尽管存储不同,也不需要更改,那么策略方法是有意义的;但是,如果UserMapper类所做的只是存储,那么一个接口和多个实现就会更简单。

您不需要任何特定的OOP设计模式。您需要的是提供功能的接口


然后,不同的数据存储应该实现它。然后,您只需要一个策略,为您的程序的工作流程提供预期的实例

您不需要任何特定的OOP设计模式。您需要的是提供功能的接口


然后,不同的数据存储应该实现它。然后,您只需要一个策略,为您的程序的工作流程提供预期的实例

我会首先创建一个带有多个实现具体类的接口,并调用接口UserDao

我将调用实现类
User{Mysql | Redis | etc}DAO
。如果您发现它们之间有任何共同的代码片段,则可以将其提取到共同的抽象基类中

此时,
UserMapper
类的逻辑可以被调用到
userdaosolver
,该类选择并在某些输入时返回具体的实现,或者如果使用某种依赖注入框架(如Spring),则可以将该函数委托给它


当前的
UserMapper
调用方将通过其接口使用DAO实现,并通过上述方法之一获得它。

我将首先使
UserMapper
成为一个具有多个实现具体类的接口,并调用接口UserDao

我将调用实现类
User{Mysql | Redis | etc}DAO
。如果您发现它们之间有任何共同的代码片段,则可以将其提取到共同的抽象基类中

此时,
UserMapper
类的逻辑可以被调用到
userdaosolver
,该类选择并在某些输入时返回具体的实现,或者如果使用某种依赖注入框架(如Spring),则可以将该函数委托给它


当前的
UserMapper
调用方将通过其接口使用DAO实现,并通过上述方法之一获得它。

只是一个警告——在您的问题中使用“最佳”可能会吸引接近票数的人支持“主要基于意见的”@user3580294,谢谢您的警告:)对我来说似乎很好。我会称之为UserDAO,而不是UserMapper,这只是一个警告——在你的问题中使用“最佳”可能会吸引接近票数的“主要基于意见的”@user3580294谢谢你的提醒:)对我来说似乎很好。我会称之为UserDAO,而不是UserMapper thoughYes,我理解它,所以在您回答之前,我刚刚删除了我的评论。:)在您描述的策略方法案例中(如果有许多操作也与存储无关),是否可以将这些与存储无关的函数执行到基类中?@zavg最好使用组合/委派,而不是继承。因此,如果有许多操作与存储无关,那么您最初提供策略的方法将更有意义。是的,我理解,所以在您回答之前,我刚刚删除了我的评论。:)在您描述的策略方法案例中(如果有许多操作也与存储无关),是否可以将这些与存储无关的函数执行到基类中?@zavg最好使用组合/委派,而不是继承。因此,如果有许多操作与存储无关,那么您最初提供策略的方法将更有意义。