java 为输入的重叠排列/组合创建可重用类

yhxst69z  于 2023-05-15  发布在  Java
关注(0)|答案(1)|浏览(247)

我遇到了一个设计问题,我有不同的实现来保存数据和处理不同工具的其他事情。我使用了一个工厂的设计来保存数据,并从数据库中获取数据。

class SaveDataService {
  public void saveData(Data data) {
  }

  public List<Tool> getTools() {
    return List.of();
  }
}

class FishToolSaveDataService extends SaveDataService {
  @Override
  public void saveData(Data data) {
  }

  @Override
  public List<Tool> getTools() {
    return List.of(Tool.FISH);
  }
}

class DogSaveDataService extends SaveDataService {
  @Override
  public void saveData(Data data) {
  }

  @Override
  public List<Tool> getTools() {
    return List.of(Tool.DOG);
  }
}
class Data {
  JsonNode data;
  int version;
}

enum Tool {
  FISH,
  DOG
}

因此,My FactoryMap器基于枚举工具
现在我有一个版本的每个工具,以维持,但保存实现的变化,为每个版本。如何在不使用if else检查的情况下维护saveData(Data数据)方法实现。
我尝试了简单的if/else检查saveData方法的版本,但如果我有五个不同的版本,并且两个不同的工具具有相同的保存不同版本的逻辑,则会延长很长时间。这是复制我的代码。
我如何设计这个版本,以便我可以重用我的代码?
我总共有15个工具实现,我从3个工具中的第2个版本开始,但在未来,更多的版本和更多的工具将到来。

mjqavswn

mjqavswn1#

问题陈述似乎能够创建类,这些类可以保存不同Tool类型和版本组合的逻辑。这是一个复杂的问题陈述,只能通过一个例子来回答。
首先创建一个接口来表示保存特定版本的逻辑:

public interface VersionDataService {
    public void saveVersionData(Data data);
}

为不同的版本定义一些具体的/通用的逻辑。

public class AlphaVersionDataService {

    public void saveVersionData(Data data) {

         //logic for saving data for alpha versions
    }
}

public class BetaVersionDataService {

    public void saveVersionData(Data data) {

         //logic for saving data for beta versions
    }
}

现在,您可能需要根据非通用工具类型执行特定逻辑。为此,您可以创建更专门的子类,例如下面的子类:

public class GammaFishVersionDataService {

    public void saveVersionData(Data data) {

         //logic for saving data for Gamma Version for Fishes only
    }
}

public class GammaDogVersionDataService {

    public void saveVersionData(Data data) {

         //logic for saving data for Gamma Version for Dogs only
    }
}

我们现在创建一个VersionDataServiceFactory来保存一个map。此Map将包含用于不同排列/组合的预先创建的VersionDataService对象。(见最后的例子,稍后会更有意义)

class VersionDataServiceFactory {

   private Map<String,VersionDataService> versionDataServicesMap;

   public VersionDataService(Map<String,VersionDataService> versionDataServicesMap) {
       this.versionDataServicesMap= versionDataServicesMap;
   }

   public VersionDataService get(int version,Tool tool) {
      //returns the pre-created object for the given version and tool combination
      return versionDataServicesMap.get(version,tool)
   }
}

class SaveDataService {

  protected VersionDataServiceFactory versionDataServiceFactory;
 
  public SaveDataFactory(SaveDataFactory versionDataServiceFactory) {
     this.versionDataServiceFactory = versionDataServiceFactory;
  }
  
  //other methods unchanged...
  
}

class FishToolSaveDataService extends SaveDataService {

    @Override
    public void saveData(Data data) {
       //get the VersionDataService instance based on the version and tool type.
       VersionDataService versionDataService = versionDataServiceFactory.get(data.getVersion(),Tool.FISH);
       //save the data.
       versionDataService.saveVersionData(data);
    }

    @Override
    public List<Tool> getTools() {
       return List.of(Tool.FISH);
    }
}

现在让我们把所有这些放在一起:

AlphaVersionDataService alpha = new AlphaVersionDataService();
GammaDogVersionDataService gammaDog = new GammaDogVersionDataService();
Map<String,VersionDataService> versionDataServicesMap = new HashMap<>();

String alphaDogKey = Tool.Dog.toString()+"1"; //just a key combination for tool type + version
String alphaFishKey = Tool.Fish.toString()+"1"; //just a key combination for tool type + version
String gammaDogKey = Tool.Dog.toString()+"2"; //just a key combination for tool type + version
map.put(alphaDogKey,alpha);
map.put(alphaFishKey,alpha);//notice how we used the same alpha object for two different Tools? This is how we saved code duplication without using if-else :)
map.put(gammaDogKey,gammaDog);

VersionDataServiceFactory factory = new VersionDataServiceFactory(versionDataServicesMap);

SaveDataService saveDataService = new FishToolDataService(factory);
saveDataService.save(data);

注意alpha对象是如何在Fish和Dog alpha版本中重用的。这就实现了在不使用if-else的情况下为不同的工具类型重用代码的目标。还要注意,当调用saveDataService.save(data);时,它会自动为给定的Tool类型和版本组合获取正确的VersionDataService实现。
注意:这是一个稍微复杂的设计问题。该代码尚未经过测试,但仅指示可以遵循的方法。还有更多的改进可以做,例如使用Decorator模式,以避免为每个版本+工具组合创建太多的子类,或者使用AbstractFactory模式,或者定义一个名为VersionDataKey的类来表示工厂Map的键等等;但这些方面是故意留给读者(包括你)去发现的,因为涵盖这些方面会使这个答案太长。

相关问题