协议继承 Swift
Protocols inheritance Swift
我是swift协议的新手,考虑Solid原则尝试使用它。我采用了两个方案(A、B)并将它们与第三个方案(D)结合起来。想法是根据需要在另一个 class 的两个协议之间进行选择。查看代码以了解更多信息。
protocol A {
func fetchA()
}
protocol B {
func fetchB()
}
protocol D : A,B { }
extension D {
func fetchB() { }
func fetchA() {}
}
class B1 : D {
func fetchB() {
print("B")
}
}
class A1 : D {
func fetchA() {
print("A")
}
}
protocol C {
func fetchC()
}
class C1 : C {
func fetchC() {
print("C")
}
}
enum Ab {
case a
case b
}
struct Hello {
let first : D
let second : C
init(first : D , second :C) {
self.first = first
self.second = second
}
func show(type:Ab){
switch type {
case .a:
first.fetchA()
case .b:
first.fetchB()
}
second.fetchC()
}
}
let obj = Hello.init(first: A1(), second: C1())
obj.show(type:.a)
所以当前代码打印“A”。现在,如果我可以将 first
参数更改为 B1() 和 type
.b
,它会打印“B”。我想改进代码库并删除 enum
类型,并希望在协议的帮助下获得相同的结果。需要在此处进行哪些更改。?提前致谢。
具体目标:我有 NetworkManger(Class A1
)、FirebaseManger(Class B1
) 和 LocalDatabaseManger(Class C1
)。我想使用 NetworkManger 或 FirebaseManger 进行网络调用,如果失败,请调用 LocalDatabaseManger。
一种方法是在符合 D
时添加额外的要求,即您指定要使用的方法。
protocol D : A,B {
func fetch()
}
class B1 : D {
func fetchB() {
print("B")
}
func fetch() {
fetchB()
}
}
class A1 : D {
func fetchA() {
print("A")
}
func fetch() {
fetchA()
}
}
struct Hello {
let first : D
let second : C
func show(){
first.fetch()
second.fetchC()
}
}
let obj = Hello.init(first: A1(), second: C1())
obj.show()
但这可能不是最好的方法,具体取决于这些协议和 类 实际上应该代表什么。
根据你的“具体目标”段落,我相信你目前有这样的事情:
class FirebaseManager {
func fetchWithFirebase() -> Bool {
print("Firebase")
return true
}
}
class NetworkManager {
func fetchFromNetwork() -> Bool {
print("Network")
return true
}
}
class LocalDatabaseManager {
func fetchFromDatabase() -> Bool {
print("Local")
return true
}
}
三个 类 不共享任何特定界面,但都可以以大致相同的方式做同样的事情。并且您希望某些客户端使用主客户端,如果不能则使用备用客户端:
class Client {
let primary: FirebaseManager
let backup: LocalDatabaseManager
init(primary: FirebaseManager, backup: LocalDatabaseManager) {
self.primary = primary
self.backup = backup
}
func show() -> Bool {
return primary.fetchWithFirebase() || backup.fetchFromDatabase()
}
}
但现在 FirebaseManger
和 LocalDatabaseManger
是硬编码的,更重要的是它们不同的 API 是硬编码的。那么如何解决呢?
这就是协议的用武之地。客户端需要一些可以获取的东西,一个 Fetcher:
protocol Fetcher {
func fetch() -> Bool
}
如果存在,那么你可以这样写客户端:
class Client {
var sources: [Fetcher]
init(sources: [Fetcher]) {
self.sources = sources
}
func show() -> Bool {
for source in sources {
if source.fetch() { return true }
}
return false
}
}
您甚至不必将自己局限于两个来源。你可以列出一个完整的清单,然后一个接一个地尝试。这很好,但是 none 的经理实际上符合 Fetcher。
这就是 Swift 协议的强大之处。您可以追溯 使类型符合协议。您甚至不必控制原始类型。您可以在任何地方执行此操作。
extension FirebaseManager: Fetcher {
func fetch() -> Bool { fetchWithFirebase() }
}
现在FirebaseManager 符合Fetcher,可以传给客户端了。您可以符合您的其余类型并将它们传递给您的客户:
extension NetworkManager: Fetcher {
func fetch() -> Bool { fetchFromNetwork() }
}
extension LocalDatabaseManager: Fetcher {
func fetch() -> Bool { fetchFromDatabase() }
}
let obj = Client(sources: [FirebaseManager(), LocalDatabaseManager()])
obj.show()
// Firebase
完全不需要继承。只需创建一个协议来表示您的算法 (show()
) 所需的行为,然后扩展您的每个类型以执行这些行为。
我是swift协议的新手,考虑Solid原则尝试使用它。我采用了两个方案(A、B)并将它们与第三个方案(D)结合起来。想法是根据需要在另一个 class 的两个协议之间进行选择。查看代码以了解更多信息。
protocol A {
func fetchA()
}
protocol B {
func fetchB()
}
protocol D : A,B { }
extension D {
func fetchB() { }
func fetchA() {}
}
class B1 : D {
func fetchB() {
print("B")
}
}
class A1 : D {
func fetchA() {
print("A")
}
}
protocol C {
func fetchC()
}
class C1 : C {
func fetchC() {
print("C")
}
}
enum Ab {
case a
case b
}
struct Hello {
let first : D
let second : C
init(first : D , second :C) {
self.first = first
self.second = second
}
func show(type:Ab){
switch type {
case .a:
first.fetchA()
case .b:
first.fetchB()
}
second.fetchC()
}
}
let obj = Hello.init(first: A1(), second: C1())
obj.show(type:.a)
所以当前代码打印“A”。现在,如果我可以将 first
参数更改为 B1() 和 type
.b
,它会打印“B”。我想改进代码库并删除 enum
类型,并希望在协议的帮助下获得相同的结果。需要在此处进行哪些更改。?提前致谢。
具体目标:我有 NetworkManger(Class A1
)、FirebaseManger(Class B1
) 和 LocalDatabaseManger(Class C1
)。我想使用 NetworkManger 或 FirebaseManger 进行网络调用,如果失败,请调用 LocalDatabaseManger。
一种方法是在符合 D
时添加额外的要求,即您指定要使用的方法。
protocol D : A,B {
func fetch()
}
class B1 : D {
func fetchB() {
print("B")
}
func fetch() {
fetchB()
}
}
class A1 : D {
func fetchA() {
print("A")
}
func fetch() {
fetchA()
}
}
struct Hello {
let first : D
let second : C
func show(){
first.fetch()
second.fetchC()
}
}
let obj = Hello.init(first: A1(), second: C1())
obj.show()
但这可能不是最好的方法,具体取决于这些协议和 类 实际上应该代表什么。
根据你的“具体目标”段落,我相信你目前有这样的事情:
class FirebaseManager {
func fetchWithFirebase() -> Bool {
print("Firebase")
return true
}
}
class NetworkManager {
func fetchFromNetwork() -> Bool {
print("Network")
return true
}
}
class LocalDatabaseManager {
func fetchFromDatabase() -> Bool {
print("Local")
return true
}
}
三个 类 不共享任何特定界面,但都可以以大致相同的方式做同样的事情。并且您希望某些客户端使用主客户端,如果不能则使用备用客户端:
class Client {
let primary: FirebaseManager
let backup: LocalDatabaseManager
init(primary: FirebaseManager, backup: LocalDatabaseManager) {
self.primary = primary
self.backup = backup
}
func show() -> Bool {
return primary.fetchWithFirebase() || backup.fetchFromDatabase()
}
}
但现在 FirebaseManger
和 LocalDatabaseManger
是硬编码的,更重要的是它们不同的 API 是硬编码的。那么如何解决呢?
这就是协议的用武之地。客户端需要一些可以获取的东西,一个 Fetcher:
protocol Fetcher {
func fetch() -> Bool
}
如果存在,那么你可以这样写客户端:
class Client {
var sources: [Fetcher]
init(sources: [Fetcher]) {
self.sources = sources
}
func show() -> Bool {
for source in sources {
if source.fetch() { return true }
}
return false
}
}
您甚至不必将自己局限于两个来源。你可以列出一个完整的清单,然后一个接一个地尝试。这很好,但是 none 的经理实际上符合 Fetcher。
这就是 Swift 协议的强大之处。您可以追溯 使类型符合协议。您甚至不必控制原始类型。您可以在任何地方执行此操作。
extension FirebaseManager: Fetcher {
func fetch() -> Bool { fetchWithFirebase() }
}
现在FirebaseManager 符合Fetcher,可以传给客户端了。您可以符合您的其余类型并将它们传递给您的客户:
extension NetworkManager: Fetcher {
func fetch() -> Bool { fetchFromNetwork() }
}
extension LocalDatabaseManager: Fetcher {
func fetch() -> Bool { fetchFromDatabase() }
}
let obj = Client(sources: [FirebaseManager(), LocalDatabaseManager()])
obj.show()
// Firebase
完全不需要继承。只需创建一个协议来表示您的算法 (show()
) 所需的行为,然后扩展您的每个类型以执行这些行为。