gpt4 book ai didi

具有使用不同参数的构造函数的 Java 简单工厂

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:01:46 26 4
gpt4 key购买 nike

我有两种方法可以在我的应用程序中保存数据:保存到数据库和保存到文件。因为我不希望客户端代码处理对象的构造,所以我创建了一个类(据我所知)是带有工厂方法的简单工厂。代码如下:

public static DataPersister createDataPersister(Boolean saveToDb, Session session, String filename) {
if (saveToDb) {
return new DatabaseDataPersister(session);
} else {
return new FileDataPersister(filename);
}
}

有了这个设置,客户端代码就不必处理构建任何东西或决定是保存到数据库还是文件 - 它只需在工厂返回的对象上调用 save() 方法像这样:

DataPersister dataPersister = DataPersisterSimpleFactory.createDataPersister(this.savetoDb, this.session, this.filename);
dataPersister.save(this.data);

我的问题是 - 这个解决方案是否违反了 SOLID 原则?为了创建例如DatabaseDataPersister 客户端代码需要传递一个 filename 参数,DataPersister 的这个实现不会用到它。我觉得它不适合类似于接口(interface)隔离原则的东西,但不完全是这样。

如果解决方案确实是一种代码味道——我该如何清理它?

最佳答案

我认为违反的 SOLID 原则是 DIP。

您的客户端类,由于必须直接依赖于静态工厂,编译时依赖于实际实现,DatabaseDataPersisterFileDataPersister,而不仅仅是抽象DataPersister

要解决此问题,请向客户端提供您希望他们使用的 DataPersister。构造函数通常是这样做的好地方:

public class ExampleClient {

private final DataPersister dataPersister;

public ExampleClient(DataPersister dataPersister) {
this.dataPersister = dataPersister;
}

public void methodThatUsesSave(){
dataPersister.save(data);
}
}

此代码在没有具体实现的情况下编译,即它不依赖于它们。客户端也不需要知道 filenamesession,因此它也解决了代码异味。

我们可以在构建的时候决定给它具体的实现,这里我用你现有的方法:

DataPersister dataPersister = DataPersisterSimpleFactory.createDataPersister(this.savetoDb, this.session, this.filename);
ExampleClient example = new ExampleClient(dataPersister);

关于具有使用不同参数的构造函数的 Java 简单工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49943700/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com