Java 应用哪种设计模式

Java 应用哪种设计模式,java,design-patterns,Java,Design Patterns,假设我们必须检索类别:Trade的数据。这个贸易类有很多参数,比如A,B,C class A { retrieveTradeDataWithA(); and many more methods which do something } class B { retrieveTradeDataWithB(); and many more methods which do something } class LetsSaySomeResource { @Inject private A

假设我们必须检索类别:Trade的数据。这个贸易类有很多参数,比如A,B,C

class A { retrieveTradeDataWithA(); and many more methods which do something }

class B { retrieveTradeDataWithB(); and many more methods which do something }

class LetsSaySomeResource {

  @Inject
  private A classAInstance;
  @Inject
  private B classBInstance;

  public void getTradeDataBasedOnA(){   
    classAInstance.retrieveTradeDataWithA();
  }
  public void getTradeDataBasedOnB(){   
    classBInstance.retrieveTradeDataWithB();
  }
}
现在的要求是,我们希望获取一些基于A和B的交易数据,稍后可能会添加更多类,如A和B,以获取基于此的数据。如何使设计更灵活

或者,C类以后可能会出现,所以我不想继续注入像A,B。。。。
有人能帮上忙吗?

首先创建一个界面,该界面将定义执行某项操作的合同:

public interface IData {
    void doSomething();
}
public class DataDAO {
    private List<IData> dataList;

    public DataDAO(List<IData> dataList) {
        this.dataList = dataList;
    }

    public void doSomething() {
        for(IData data : dataList) {
            data.doSomething();
        }
    }
}
然后创建具体的实现来做一些事情:

public class DataA implements IData {

    @Override
    public void doSomething() {
        // TODO Do something for A

    }

}

public class DataB implements IData {

    @Override
    public void doSomething() {
        // TODO Do something for B
    }

}
最后一个类将实际执行某些操作:

public interface IData {
    void doSomething();
}
public class DataDAO {
    private List<IData> dataList;

    public DataDAO(List<IData> dataList) {
        this.dataList = dataList;
    }

    public void doSomething() {
        for(IData data : dataList) {
            data.doSomething();
        }
    }
}
公共类DataDAO{
私有列表数据列表;
公共数据DAO(列表数据列表){
this.dataList=dataList;
}
公共无效剂量测定法(){
对于(IData数据:数据列表){
数据。doSomething();
}
}
}
现在让我们来看一下您的用例:

为某个目标做点什么:

 List<IData> dataAList = new ArrayList<IData>();
 dataList.add(new DataA());
 DataDAO dataADAO = new DataDAO(dataAList);
 dataADAO.doSomething();
List datalist=new ArrayList();
添加(新的DataA());
DataDAO dataADAO=新的DataDAO(dataAList);
dataADAO.doSomething();
为A和B做点什么:

 List<IData> dataAList = new ArrayList<IData>();
 dataList.add(new DataA());
 dataList.add(new DataB());
 DataDAO dataADAO = new DataDAO(dataAList);
 dataADAO.doSomething();
List datalist=new ArrayList();
添加(新的DataA());
add(newdatab());
DataDAO dataADAO=新的DataDAO(dataAList);
dataADAO.doSomething();

它可能看起来像这样:

class LetsSaySomeResource {
    @Resource
    private Map<String, DataAccessInterface> instanceToDataAccessMapping;

    public DateAggregationResult getDataFor(String... instanceNames) {
        DataAggregationResult result = new DataAggregationResult(); // some list or whatever
        for (String instanceName : instanceNames) {
            Data data = instanceToDataAccessMapping.get(instanceName).getData();
            /**
             * Add this data to aggregation result here
             */
        }
        return result;
    }
}
类LetsSaySomeResource{
@资源
私有映射instanceToDataAccessMapping;
public DateAggregationResult getDataFor(字符串…实例名称){
DataAggregationResult=新建DataAggregationResult();//某些列表或其他
对于(字符串instanceName:instanceNames){
数据数据=instanceToDataAccessMapping.get(instanceName.getData();
/**
*将此数据添加到此处的聚合结果
*/
}
返回结果;
}
}
试试类似的方法。如果您的类总是基于以前的需求随时间增长,那么您可以通过装饰它们来添加额外的计算

您的示例仍然非常抽象,因此很难判断您的附加类是相互依赖的还是简单的“扩展”(简单的继承就可以了)


或者完全解耦,这样SimY4就可以提供帮助(例如使用的变体)。

我认为模板设计模式在这里很有用


您可以在基类中定义模板方法,并让实现该类的子类定义自己的算法来实现这一点。一定要阅读维基链接,你就会找到出路。

DoSomthingForAndB呢?你的答案只能涵盖dosomthingfora或doSomthingForB,但不能同时涵盖两者。请看我的答案。您可以允许将多个instanceNames传递给Resource方法,并在返回实际数据之前聚合结果。我看这里没有任何问题。是的,但是getDataFor是一维的。我的意思是,它一次只能在instanceName上操作,所以不管映射中有多少条目。调用者必须多次调用这个getDataFor方法,这使得映射毫无意义。现在,如果您要在getDataFor方法中迭代映射,这将是有意义的。但再说一遍,既然你可以使用列表,为什么还要使用地图呢?我仍然不同意使用地图,因为它没有任何用途。您不仅需要维护表示方法调用的字符串,还需要每次迭代并调用映射上的get。传递给此方法的DataAccessInterface的简单列表就足够了。请看我的答案。字符串、枚举、整数等都不重要。你不需要那些额外的占位符。此外,在这种特殊情况下,地图将占用更多空间。想想看。您必须为所有将用作键的方法名定义常量:doSomethingForA、doSomethingForB…..doSomethingForZ。想象一下当你有100种方法时会发生什么?这不仅是维护的噩梦,而且是不必要的开销。即使只有4个或5个方法,为键设置占位符仍然是不必要的开销。嗨,我认为如果我想一起过滤,这无法解决AandB参数的问题。我已经对我的需求进行了编辑,以使其更加清晰,希望这能帮助我了解一些情况。使用上述解决方案,您不需要继续注入过滤器。您只需要创建一个具体的IData实现列表,正如我在回答的最后一段中所示。您好,我对我的需求进行了编辑,使其更加清晰,希望这能帮助我提供一些想法。我怀疑类似这样的东西可以帮助您-使用列表可以消除使用装饰器模式的需要。