2016-03-27 5 views
0

私はUserManagerという名前のクラスを持っています。このSwiftクラスから継承できるようにベースを作成するにはどうすればよいですか?

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と呼ばれるオブジェクトを持っている、そしてそれは、このクラスではどこでも使われていることに注意してください。

PostManagerAdminManagerというクラスがあり、上記のクラスと同じロジックが使用されています。

私は単純にコピーして、上記のコードを貼り付け、PostAdminでオブジェクトにUser置き換えることができます。しかし、明らかにこれは悪い習慣です。

リソースを受け入れるには、このクラスで何ができますか?だけでなく、User

+0

@matt現在のクラスは、オブジェクトとして '' 'User'''を受け入れます。私は任意のオブジェクトを使用できるように任意にしたいです。今のところ、多くの方法で '' User'''を返すことは難しいです。 – TIMEX

+0

「共通のスーパークラスから派生する」方法これは私が助けが必要なところです: – TIMEX

答えて

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)方法は、マネージャークラスのバリアントを持つことができている。一般的なクラスは、静的プロパティを持つことができないので、それはサブクラスに移動されますので注意してください。

+0

'class manager 'というシンタックスは、マネージャを "一般的な"クラスにしているので、参考資料(Appleの素早い本を含む)で見つけることができます。 > 'はTがManageableを実装しなければならないと言います。 –

0

継承が実装を隠すことができることを考えます詳細、参照semanti csは必要ではなく、プロトコル+関連型(ジェネリック)の実装は構造体を使用する方が安全であり、おそらくもっと "Swifty"でしょう。

関連するタイプ(スウィフト2.2)またはタイプエイリアス(スウィフト2.1)を使用してプロトコルを定義します。

そして、あなたの実装は次のようになります。

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)。

+0

Swift 2.2では、プロトコルの' typealias'が 'associatedtype'に置き換えられました。 – BallpointBen

関連する問題