哪种设计模式更适合保存/删除数据,为什么? - java

我无法例如在以下两种模式之间进行选择。保存一个dataObject(在我的情况下为bean)。这两个选项是:

第一

abstract class DataService {
    protected void save(Object data){
        //persist the data
    }
}
//the service for Project objects
class ProjectService extends DataService {
    public void saveProject(Project prj, Object... args /*other save options*/ ){
        // some preprocessing, checking, validation
        save(prj); //call the method in DataService
        // do postprocessing
    }
}

//calling save
projectService.saveProjec(project, /*some args*/);

第二名

abstract class DataService {
    public void save(Object data){
        if(beforeSave(data)){
            // persist the data
            afterSave(data);
        }
    }
    protected boolean beforeSave(){
        return true;
    }
    protected void afterSave(){
    }
}

//the service for Project objects
class ProjectService extends DataService {
    public initSave(Object... args /*other save options*/ ){
        // store these options in class properties
    }
    @Override
    protected bool beforeSave(Project objectAboutToBeSaved){
        // some preprocessing, checking, validation
        // use class properties set by initSave if needed
        return true;//if we want to continue with the saving procedure
    }

    @Override
    protected bool afterSave(Project savedObject){
        // do postprocessing
        // use class properties set by initSave if needed
    }
}

//calling save
projectService.initSave(/*some args*/);
projectService.save(project);

目前,我们正在使用第一种模式,但是我开始考虑转向第二种模式,因为:

(专业人士)

更好的逻辑分离
跨多个对象类型命名的统一方法(将允许创建通用单元测试:例如,初始化每个对象及其服务并调用保存)

(缺点)

设置起来有点困难(initSave)-甚至可能必须包含拆解方法

这个想法来自CakePHP MVC框架,其中模型和控制器都包含此类回调方法,使用它们我可以真正实现一些清晰的业务逻辑。

现在,我正在使用Java-Spring + Spring Data Graph-(因此是Javaish代码)进行开发,但是在我看来,这个问题可能是一个非常普通的问题。

注意:该示例是为保存而给出的,但是对于删除过程也是如此。

参考方案

另一个解决方案是使用策略模式并执行以下操作。
我们正在使用这种方法进行持久性验证,有时甚至计算(基于其他字段)并设置要持久化的数据对象的某些字段(例如,我们有一个“ complete”标志,该标志根据其他字段进行更新字段,只要持久存在或更新我们的实体之一)。

您的策略:

interface SaveStrategy<T> {
  boolean beforeSave(T data);
  void afterSave(T data);
}

class SomeFancyProjectSaveStrategy implements SaveStrategy<Project> {

  public SomeFancyProjectSaveStrategy( /*parameters*/) {
  } 

  public boolean beforeSave(Project data) {
     //whatever you like
  }

  public void afterSave(Project data) {
     //whatever you like
  }
}

您的数据服务:

class DataService {
  public <T> void save(T data, SaveStrategy<? super T> strategy ){
    if(strategy.beforeSave(data)){
        // persist the data
        strategy.afterSave(data);
    }
  }
}

然后像这样使用它们:

SaveStrategy<Project> saveStrategy = new SomeFancyProjectSaveStrategy(someParameters); //could reuse that
dataService.save( project, saveStrategy); //the service might even be shared for different data objects

优点:

保存前和保存后的操作与持久性分离
您可以重用策略,只要它们包含可重用的数据(如验证规则但不包含状态)。
您可以使用常规的DataService

缺点

如果您需要特殊的保存逻辑,则可能必须维护至少两个类:策略和特殊数据服务

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

Java:BigInteger,如何通过OutputStream编写它 - java

我想将BigInteger写入文件。做这个的最好方式是什么。当然,我想从输入流中读取(使用程序,而不是人工)。我必须使用ObjectOutputStream还是有更好的方法?目的是使用尽可能少的字节。谢谢马丁 参考方案 Java序列化(ObjectOutputStream / ObjectInputStream)是将对象序列化为八位字节序列的一种通用方法。但…

Java-如何将此字符串转换为日期? - java

我从服务器收到此消息,我不明白T和Z的含义,2012-08-24T09:59:59Z将此字符串转换为Date对象的正确SimpleDateFormat模式是什么? java大神给出的解决方案 这是ISO 8601标准。您可以使用SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM…

Java:从类中查找项目名称 - java

仅通过类的实例,如何使用Java反射或类似方法查找项目名称?如果不是,项目名称(我真正想要的是)可以找到程序包名称吗? 参考方案 项目只是IDE使用的简单组织工具,因此项目名称不是类或JVM中包含的信息。要获取软件包,请使用Class#getPackage()。然后,可以调用Package#getName()将包作为您在代码的包声明中看到的String来获取…

Spring Data Cassandra的事务管理 - java

我正在使用Spring和Cassandra作为基础数据库。曾提到过弹簧伞项目“ spring data cassandra”。与休眠不同,在这里无法找到如何管理事务。如果您中的某些人已经合并,请共享要包含的事务管理器的详细信息。 参考方案 Cassandra不支持传统(ACID)的事务。在某些特殊情况下,可以通过一些构造来实现事务原子性,例如原子批处理(请参…