我对程序架构有疑问。 我经常遇到以下问题:
假设我们的服务器上有一组对象。一个对象包含一个简短的描述(让我们称之为description
)和一个沉重的fullData
。
我们有一个客户端应用程序,它只下载description
的对象列表。当用户选择列表中的一个项目时,将加载此项目的fullData
。
我通常会实现某种dataSource
对象,它会加载descriptions
s的元素列表。但是我们必须从服务器获取fullData
。
我通常这样做:在fetchFullDataForObject(MyObject object)
中实现DataSource
(伪代码)之类的方法。
问题在于,在这种情况下,对象变得依赖于dataSource(如果我们想要访问对象的fullData
,我们要么必须检查它是null
还是自己调用fetchFullData
,或者在Object中隐式调用它(在这种情况下,对象必须保持对它所属的dataSource的引用,我在下面的伪代码中实现了这个选项))。在这两种情况下,我们都必须引用dataSource
。
另一种选择是保存用于在Objects类中获取fullData
的代码。但在这种情况下,Object包含客户端 - 服务器交互的逻辑。对我来说这看起来不是一个好习惯。
此类情况的最佳做法是什么?下载fullData
的责任是谁?可能存在一些在这种情况下使用的常见设计模式?
我在下面实施了一个可能的选项。因为它不是特定的(在我看来)开发语言,所以我用伪代码写了它。
//pseudocode
class Object
{
private String description;
private Data fullData = null;
DataSource dataSource;
public Object(String description, DataSource dataSource)
{
this.description = description;
this.dataSource = dataSource;
}
public String getDescription()
{
return this.description;
}
public Data getFullData()
{
if (fullData == null)
this.dataSource.fetchFullDataForObject(this); //one of possible options
return fullData;
}
};
class DataSource
{
private List<Object> objects = null;
private void loadItemsFromServer(); //loads objects (without fullData) and saves them to the "objects" list
public List<Object> getObjects()
{
if (objects == null)
loadItemsFromServer();
return objects;
}
public void fetchFullDataForObject(Object object);
};
答案 0 :(得分:1)
你是对的,从Object
到dataSource
的引用不是一个好习惯,因为:
dataSource
对象类似于Repository模式实现。Object
与域实体类似。最好拆分数据访问和域模型。
因此,您有以下选择:
您可以提取IDataSource
界面并将其放入您的域模型中。其实施DataSource
可以在您的数据访问层中。
您可以传递一个函数(例如anonymous function),而不是传递IDataSource
/ DataSource
的实例。
您可以传递IDataSource
的实例,而不是将DataSource
/ Data
的实例传递给构造函数。为了实现延迟加载,可以使用Data
中的派生类型(例如,在数据访问中实现的LazyData
)。有时LazyData
类型的实施方式与decorator类似。
这些链接可能会有所帮助: