对于可以从不同来源接收数据的单个对象,我需要什么设计模式?
What design pattern do I need for a single object which can receive data from different sources?
我正在尝试在 Swift 中创建一些代码来启用以下功能。有一个 class(称之为数据存储)是代码的主要接口 - 这是 API 的大多数用户大部分时间都会处理的。
这个数据存储 class 是灵活的。您可以将它与来自文本文件的数据、蓝牙数据或通过 WiFi 传入的数据等一起使用。我称这些为数据提供者。因此,例如,您可以有一个 BTProvider class,它会获取蓝牙数据并在数据到达时将其发送到数据存储区。一个数据存储永远不需要从多个数据提供者获取数据。
哪些设计模式或语言工具可以帮助我实现这一目标?
我考虑过使用协议,但感觉倒退了 - 协议定义了一个对象可以响应哪些方法 - 但在这种情况下,这将是 Datastore 对象 - 只有一个。在我的脑海里,我觉得我想要一个反向协议——我可以保证 "this object /calls/ these methods on another object" 的东西。然后所有的提供者都可以实现这个,数据存储可以有一个方法"setProvider: ProviderOfData",其中数据提供者是反向协议的名称。
如果我可以从数据存储中轮询提供程序,这会容易得多(然后他们可以实现一个协议来定义像 'getMostRecentData' 这样的方法,但由于它的性质(从 WiFi 接收异步数据、蓝牙等)这是不可能的,而且感觉不优雅 - 但如果你有想法,我愿意接受!
这似乎不是第一次这样做,所以我对它的常见做法很感兴趣,这样我就不必重新发明轮子了。
something where I can guarantee "this object /calls/ these methods on another object".
看来你需要的是 Delegate-Pattern
你可以有一个 DataStore
(Swift 是驼峰式),这个 class 可以实现几个委托协议。示例:
class DataStore {
// logic of the DataStore
}
你说你的应用程序主要是一个 class(DataStore
),所以我猜你有人从它初始化你的提供者。我会建议:
// Provider Factory
extension DataStore {
func makeBluetoothProvider() {
let btProvider = BTProvider()
btProvider.delegate = self
}
// creation of other providers, or you can create them all at once.
}
不是重要的部分,DataStore
是您的提供者的委托,这样,当他们检索数据时,他们可以调用 DataStore
。我会有这样的协议:
protocol ProviderDelegate: class {
func provider(_ provider: Provider, didFinishReceiving data: Data)
}
extension DataStore: ProviderDelegate {
func provider(_ provider: Provider, didFinishReceiving data: Data) {
// read data and do something with it...display it, save it, etc.
}
}
Provider
将是所有提供商的通用 class,可能具有网络请求或类似的基本数据。一个例子是:
class Provider {
var delegate: ProviderDelegate
var data: Data
}
class BTProvider: Provider {
// logic only for bluetooth provider
}
根据您的提供者行为的不同,您可以为每个提供者都有一个委托协议,并扩展 DataStore
实现每个协议。只有当行为彼此差异太大时,我才不这么认为。
更新地址注释:协议可以提供代码
协议可以提供代码,举个例子:
protocol Provider {
weak var delegate: ProviderDelegate { get set }
func fetchData(with url: URL)
func processData(data: Data)
}
extension Provider {
func processData(data: Data) {
// do some processing that all providers have to do equally
// probably also call delegate to tell DataStore it is ready
}
}
您的提供者 class 将实施该方法,并且可以选择实施新的 processData
或仅使用 默认 方法。如果它实现了它,则无需调用 override
,您将不再有权访问协议方法。您的提供商可以如下所示:
class BTProvider: Provider {
weak var delegate: Provider?
func fetchData(with url: URL) {
// do some logic to fetch data for this provider
processData(data: whateverWasFetched)
}
}
我正在尝试在 Swift 中创建一些代码来启用以下功能。有一个 class(称之为数据存储)是代码的主要接口 - 这是 API 的大多数用户大部分时间都会处理的。
这个数据存储 class 是灵活的。您可以将它与来自文本文件的数据、蓝牙数据或通过 WiFi 传入的数据等一起使用。我称这些为数据提供者。因此,例如,您可以有一个 BTProvider class,它会获取蓝牙数据并在数据到达时将其发送到数据存储区。一个数据存储永远不需要从多个数据提供者获取数据。
哪些设计模式或语言工具可以帮助我实现这一目标?
我考虑过使用协议,但感觉倒退了 - 协议定义了一个对象可以响应哪些方法 - 但在这种情况下,这将是 Datastore 对象 - 只有一个。在我的脑海里,我觉得我想要一个反向协议——我可以保证 "this object /calls/ these methods on another object" 的东西。然后所有的提供者都可以实现这个,数据存储可以有一个方法"setProvider: ProviderOfData",其中数据提供者是反向协议的名称。
如果我可以从数据存储中轮询提供程序,这会容易得多(然后他们可以实现一个协议来定义像 'getMostRecentData' 这样的方法,但由于它的性质(从 WiFi 接收异步数据、蓝牙等)这是不可能的,而且感觉不优雅 - 但如果你有想法,我愿意接受!
这似乎不是第一次这样做,所以我对它的常见做法很感兴趣,这样我就不必重新发明轮子了。
something where I can guarantee "this object /calls/ these methods on another object".
看来你需要的是 Delegate-Pattern
你可以有一个 DataStore
(Swift 是驼峰式),这个 class 可以实现几个委托协议。示例:
class DataStore {
// logic of the DataStore
}
你说你的应用程序主要是一个 class(DataStore
),所以我猜你有人从它初始化你的提供者。我会建议:
// Provider Factory
extension DataStore {
func makeBluetoothProvider() {
let btProvider = BTProvider()
btProvider.delegate = self
}
// creation of other providers, or you can create them all at once.
}
不是重要的部分,DataStore
是您的提供者的委托,这样,当他们检索数据时,他们可以调用 DataStore
。我会有这样的协议:
protocol ProviderDelegate: class {
func provider(_ provider: Provider, didFinishReceiving data: Data)
}
extension DataStore: ProviderDelegate {
func provider(_ provider: Provider, didFinishReceiving data: Data) {
// read data and do something with it...display it, save it, etc.
}
}
Provider
将是所有提供商的通用 class,可能具有网络请求或类似的基本数据。一个例子是:
class Provider {
var delegate: ProviderDelegate
var data: Data
}
class BTProvider: Provider {
// logic only for bluetooth provider
}
根据您的提供者行为的不同,您可以为每个提供者都有一个委托协议,并扩展 DataStore
实现每个协议。只有当行为彼此差异太大时,我才不这么认为。
更新地址注释:协议可以提供代码
协议可以提供代码,举个例子:
protocol Provider {
weak var delegate: ProviderDelegate { get set }
func fetchData(with url: URL)
func processData(data: Data)
}
extension Provider {
func processData(data: Data) {
// do some processing that all providers have to do equally
// probably also call delegate to tell DataStore it is ready
}
}
您的提供者 class 将实施该方法,并且可以选择实施新的 processData
或仅使用 默认 方法。如果它实现了它,则无需调用 override
,您将不再有权访问协议方法。您的提供商可以如下所示:
class BTProvider: Provider {
weak var delegate: Provider?
func fetchData(with url: URL) {
// do some logic to fetch data for this provider
processData(data: whateverWasFetched)
}
}