gpt4 book ai didi

java - 将服务逻辑与数据分离

转载 作者:太空狗 更新时间:2023-10-29 22:57:56 24 4
gpt4 key购买 nike

我一直在查看我在一个 android 项目中的几个类,我意识到我一直在将逻辑与数据混合在一起。意识到这对我的项目的可读性和可测试性有多糟糕后,我决定进行一些重构,以便将所有服务逻辑抽象到单独的服务模块中。但是,由于我一直依赖 Java 的多态性,所以我迷路了,需要一些指导。

假设我有一个 super 数据类和两个子类的“待更改”布局:

public class DataItem {
/* some variables */

public saveToDB(/* Some Arguments */) {
/* do some stuff */
}

public render() {
/* render the class */
}
}

public class ChildDataItemA extends DataItem {
@Override
public saveToDB(/* Some Arguments */) {
super.saveToDB();
/* more specific logic to ChildDataItemA */
}

@Override
public render() {
/* render logic for ChildDataItemA */
}
}

public class ChildDataItemB extends DataItem {
@Override
public saveToDB(/* Some Arguments */) {
super.saveToDB();
/* more specific logic to ChildDataItemB */
}

@Override
public render() {
/* render logic for ChildDataItemB */
}
}

现在,我考虑将 saveToDB()render() 方法移动到服务类。但是,有时我需要能够在不知道其运行时类型的情况下将这些方法调用到已编译类型 DataItem 的实例中。例如,我可能想进行以下调用:

List<DataItem> dataList; 
for (DataItem item: dataList) {
item.saveToDB();
item.render();
}

此外,我想到了以下操作:

public class ChildDataItemB extends DataItem {
@Override
public saveToDB(/* Some Arguments */) {
super.saveToDB();
/* more specific logic to ChildDataItemB */
Service.saveToDBB();
}

@Override
public render() {
/* render logic for ChildDataItemB */
Service.renderB();
}
}

我仍然在每个将调用适当服务方法的子类中保留“虚拟”方法。但是,我不认为这真的实现了我想要的分离,因为数据类仍然知道服务(不好!)。

关于如何解决这个问题有什么想法吗?

编辑:请注意,render()saveToDB() 只是这些方法的一般示例,因此问题不在于选择 ORM 或SQL相关技术。

最佳答案

Visitor pattern救援。创建访问者接口(interface)并让每个服务实现此接口(interface):

public interface DataItemVisitor {
// one method for each subtype you want to handle
void process(ChildDataItemA item);
void process(ChildDataItemB item);
}

public class PersistenceService implements DataItemVisitor { ... }
public class RenderService implements DataItemVisitor { ... }

然后让每个 DataItem 实现一个 accept 方法:

public abstract class DataItem {
public abstract void accept(DataItemVisitor visitor);
}

public class ChildDataItemA extends DataItem {
@Override
public void accept(DataItemVisitor visitor) {
visitor.process(this);
}
}

public class ChildDataItemB extends DataItem {
@Override
public void accept(DataItemVisitor visitor) {
visitor.process(this);
}
}

请注意,所有 accept 实现看起来都一样,但 this 指的是每个子类中的正确类型。现在您可以添加新服务而无需更改 DataItem 类。

关于java - 将服务逻辑与数据分离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11682784/

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