java void函数式编程、紧耦合和样板

java void函数式编程、紧耦合和样板,java,functional-programming,boilerplate,tightly-coupled-code,Java,Functional Programming,Boilerplate,Tightly Coupled Code,当目标对象excelColumns,pdfColumns部分共享相同的对象,其中一些对象甚至是有条件共享时,有什么好的OOP模式可以避免下面代码中的函数式编程、紧耦合和样板文件?让我们假设,将有许多共享列,只有少数非共享和条件列 List<Column> excelColumns = new ArrayList<>(); List<Column> pdfColumns = new ArrayList<>(); //shar

当目标对象
excelColumns
pdfColumns
部分共享相同的对象,其中一些对象甚至是有条件共享时,有什么好的OOP模式可以避免下面代码中的函数式编程、紧耦合和样板文件?让我们假设,将有许多共享列,只有少数非共享和条件列

    List<Column> excelColumns = new ArrayList<>();
    List<Column> pdfColumns = new ArrayList<>();

    //shared columns
    Column test = new Column("test", 121, 11);
    excelColumns.add(test);
    pdfColumns.add(test);

    //conditional columns
    if (condition) {
        excelColumns.add(new Column("test2", 12, 21));
    }

    //non shared columns
    pdfColumns.add(new Column("test3", 12, 41));

    //shared columns
    Column test4 = new Column("test4", 12, 331);
    excelColumns.add(test4);
    pdfColumns.add(test4);
    Column test5 = new Column("test5", 72, 11);
    excelColumns.add(test5);
    pdfColumns.add(test5);
    Column test6 = new Column("test6", 82, 121);
    excelColumns.add(test6);
    pdfColumns.add(test6);
listcelcolumns=newarraylist();
List pdfColumns=new ArrayList();
//共享列
列测试=新列(“测试”,121,11);
添加(测试);
pdfColumns.add(测试);
//条件列
如果(条件){
添加(新列(“test2”,12,21));
}
//非共享列
添加(新列(“test3”,12,41));
//共享列
列test4=新列(“test4”,12331);
添加(test4);
pdfColumns.add(test4);
列test5=新列(“test5”,72,11);
添加(test5);
pdfColumns.add(test5);
列test6=新列(“test6”,82,121);
添加(test6);
pdfColumns.add(test6);

您可以使用
addAll(…)
方法,而不是
add(…)
为最后一个共享列部分添加所有集合。如果您的目标是保持插入下一列的有条件顺序,那么就没有必要混淆它,因为这里清楚地显示了它。

根据您对复杂性的偏好,您可以执行以下操作:

  • 尝试将相关列实例分组到对象中,如
    HeaderColumns
    BodyColumns
  • 实现所描述的访问者模式
  • 下面是根据上述建议可能实现的模式:

    公共类主{
    界面访问者{
    无效访问(报告标题);
    无效访问(报告主体);
    }
    界面可访问{
    无效接受(访客);
    }
    静态类ReportHeader实现Visitable{
    private final List columns=new ArrayList();
    private final List extras=new ArrayList();
    @凌驾
    公共无效接受(访客){Visitor.visit(this);}
    公共列表getColumns(){return columns;}
    public List getExtras(){return extras;}
    }
    静态类ReportBody实现Visitable{
    private final List columns=new ArrayList();
    @凌驾
    公共无效接受(访客){Visitor.visit(this);}
    公共列表getColumns(){return columns;}
    }
    静态类ExcelReportVisitor实现Visitor{
    private final List columns=new ArrayList();
    @凌驾
    公共无效访问(报告标题){
    columns.addAll(header.getColumns());
    columns.addAll(header.getExtras());
    }
    @凌驾
    public void访问(ReportBody body){columns.addAll(body.getColumns());}
    }
    静态类PdfReportVisitor实现Visitor{
    private final List columns=new ArrayList();
    @凌驾
    公共无效访问(报告标题){
    columns.addAll(header.getColumns());
    //没有额外的PDF格式
    }
    @凌驾
    public void访问(ReportBody body){columns.addAll(body.getColumns());}
    }
    }
    
    您可以按如下方式使用它:

    publicstaticvoidmain(字符串参数[]){
    ReportHeader header=新的ReportHeader();
    ReportBody=新的ReportBody();
    List visitors=Arrays.asList(新的PdfReportVisitor(),新的ExcelReportVisitor());
    访客。forEach(每个->{
    每次访问(页眉);
    每次访问(机构);
    });
    //对访问者执行类似“visitor.exportReport()的操作”`
    }
    
    这种方法的优点:

  • 每次您必须向
    Visitor
    添加新的报告节时,它都会在所有Visitor实现中生成编译错误。这避免了人们忘记在
    if
    switch
    语句中添加分支的典型编程错误
  • 关于如何构建报告的条件逻辑放在报告的实际实现中。不再需要有条件的
  • 这种方法的缺点:

  • 考虑到您需要创建的额外抽象,请确保复杂性
  • 有时,将
    实例封装/分组到语义内聚的对象中可能没有意义或可能。例如,您可能会在
    ReportHeader
    中以古怪结尾,如下所示:
  • 静态类ReportHeader实现Visitable{
    private final List columns=new ArrayList();
    private final List extras=new ArrayList();
    私有最终列表数据为NLYUSEDBYEXCELREPORT=new ArrayList();
    @凌驾
    公共无效接受(访客){Visitor.visit(this);}
    公共列表getColumns(){return columns;}
    public List getExtras(){return extras;}
    公共列表GetDataThatIsonlySedByExcelReport(){返回DataThatIsonlySedByExcelReport;}
    }
    
    谢谢@marcin.programuje,但是如何避免
    excelColumns
    pdfColumns
    之间的紧密耦合,假设我希望在不同的类中实现?然后您可以使用策略模式。假设您希望将
    excelColumns
    集合构建过程与
    pdfColumns
    集合构建过程分离,您可以创建一个类
    ExcelColumnsBuildingsStrategy
    PDFColumnsBuildingsStrategy
    。这两个类将实现相同的接口
    ColumnsBuildingsStrategy
    。更多信息请点击此处: