我有一个名为UserManager
的课程。
public class UserManager{
static let sharedInstance = UserManager()
let center = NSNotificationCenter.defaultCenter()
let queue = NSOperationQueue.mainQueue()
var resources = Dictionary<Int, User>()
var clients = Dictionary<Int, Set<String>>()
private init(){
}
private func addToClientMap(id: Int, clientName: String){
if clients[id] == nil {
clients[id] = Set<String>()
clients[id]!.insert(clientName)
}else{
clients[id]!.insert(clientName)
}
}
func getResource(id: Int, clientName: String) -> User?{
if let resource = resources[id] {
addToClientMap(id, clientName: clientName)
return resource
}else{
return nil
}
}
func createResource(data:JSON, clientName: String) -> User? {
if let id = data["id"].int {
if let resource = resources[id] {
addToClientMap(id, clientName: clientName)
return resource
}else{
resources[id] = mapJSONToUser(data) //need to make generic
addToClientMap(id, clientName: clientName)
return resources[id]
}
}
return nil
}
func releaseResource(id: Int, clientName: String){
if clients[id] != nil {
clients[id]!.remove(clientName)
if clients[id]!.count == 0 {
resources.removeValueForKey(id)
clients.removeValueForKey(id)
}
}
}
}
请注意,我有一个名为User
的对象,它在本课程的任何地方都使用过。
我希望有一个名为PostManager
和AdminManager
的课程,它们使用与上述课程相同的逻辑。
我可以简单地复制并粘贴上面的代码,并使用User
和Post
替换对象Admin
。但是......显然这是不好的做法。
我该怎么做才能接受任何资源?不只是User
答案 0 :(得分:1)
这样做最明显的方法是将所有通用功能嵌入到泛型类中,然后继承你的UserManager:
protocol Managable {
init(json:JSON)
}
public class Manager<T:Manageable> {
let center = NSNotificationCenter.defaultCenter()
let queue = NSOperationQueue.mainQueue()
var resources = Dictionary<Int, T>()
var clients = Dictionary<Int, Set<String>>()
private init(){
}
private func addToClientMap(id: Int, clientName: String){
if clients[id] == nil {
clients[id] = Set<String>()
clients[id]!.insert(clientName)
}else{
clients[id]!.insert(clientName)
}
}
func getResource(id: Int, clientName: String) -> T?{
if let resource = resources[id] {
addToClientMap(id, clientName: clientName)
return resource
}else{
return nil
}
}
func createResource(data:JSON, clientName: String) -> T? {
if let id = data["id"].int {
if let resource = resources[id] {
addToClientMap(id, clientName: clientName)
return resource
}else{
resources[id] = T(json:data) //need to make generic
addToClientMap(id, clientName: clientName)
return resources[id]
}
}
return nil
}
func releaseResource(id: Int, clientName: String){
if clients[id] != nil {
clients[id]!.remove(clientName)
if clients[id]!.count == 0 {
resources.removeValueForKey(id)
clients.removeValueForKey(id)
}
}
}
}
class User : Managable {
required init(json:JSON) {
}
}
class UserManager : Manager<User> {
static var instance = UserManager()
}
现在,任何实现Manageable
协议的类(即,它具有init(json:JSON)
方法都可以具有Manager类变体。请注意,因为泛型类不能具有静态属性,这已被移入子类。
答案 1 :(得分:0)
鉴于继承可以隐藏实现细节,如果不需要引用语义,则使用结构的协议+关联类型(泛型)实现可能更安全,可以说更“Swifty”。
使用关联类型(Swift 2.2)定义您的协议或输入别名(Swift 2.1):
protocol Manager {
associatedtype MyManagedObject // use typealias instead for Swift 2.1
func getResource(id: Int, clientName: String) -> MyManagedObject?
func createResource(data: JSON, clientName: String) -> MyManagedObject?
func releaseResource(id: Int, clientName: String)
}
然后您的实施变为:
public struct UserManager: Manager {
typealias MyManagedObject = User
func getResource(id: Int, clientName: String) -> User? { ... }
func createResource(data: JSON, clientName: String) -> User? { ... }
func releaseResource(id: Int, clientName: String) { ... }
}
您可以轻松地使用相同的协议进一步添加对象,指定“MyManagedObject”应该是什么:
public struct PostManager: Manager {
typealias MyManagedObject = Post
func getResource(id: Int, clientName: String) -> Post? { ... }
func createResource(data: JSON, clientName: String) -> Post? { ... }
func releaseResource(id: Int, clientName: String) { ... }
}
我建议详细阅读有关协议和泛型的更多信息(网上有很多例子,Apple's documentation is a good place to start)。