Sam*_*Sam 15 java service design-patterns
我一直在查看我在android项目中的几个类,我意识到我一直在混合逻辑和数据.在意识到这对我的项目的可读性和测试能力有多糟糕之后,我决定进行一些重构,以便将所有服务逻辑抽象出来以分离服务模块.但是,由于我一直依赖Java的多态性,我迷路了,需要一些指导.
假设我有一个超级数据类的"待更改"布局,以及两个子类:
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 */
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我考虑将saveToDB()
和render()
方法移动到服务类.但是,有时我需要能够在DataItem
不知道其运行时类型的情况下将这些方法调用到已编译类型的实例中.例如,我可能想要进行以下调用:
List<DataItem> dataList;
for (DataItem item: dataList) {
item.saveToDB();
item.render();
}
Run Code Online (Sandbox Code Playgroud)
另外,我想到了以下几点:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
我仍然在每个子类中保留"虚拟"方法,这些方法将调用适当的服务方法.但是,我不认为这真的实现了我想要的分离,因为数据类仍然会知道服务(糟糕!).
关于如何解决这个问题的任何想法?
编辑:请注意,render()
和saveToDB()
只是什么这些方法可以通用的例子,所以这个问题是不是真正的选择一个ORM或SQL相关技术.
访客模式救援.创建访问者界面并让每个服务实现此界面:
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 { ... }
Run Code Online (Sandbox Code Playgroud)
然后每个都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);
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,所有accept
实现看起来都相同,但是this
指的是每个子类中的正确类型.现在,您无需更改DataItem
类即可添加新服务.
归档时间: |
|
查看次数: |
1713 次 |
最近记录: |