2015-08-07 17 views
10

mam jedną klasę z metod statycznych: ta klasa owija połączenia do API Twitteradwóch klas, zwrotna i testów jednostkowych

W drugiej klasie, mam pewną logikę biznesową.

Ze względu na zachowanie asynchroniczności niektórych metod w klasie opakowania, mam trudności z zaprojektowaniem komunikacji. Oto co zrobiłem:

APIManager.swift

public class APIManager { 
    class func getPermission(callback :() -> Void) { 

     let accountStore = ACAccountStore() 
     let accountType = 
     ACAccountStore().accountTypeWithAccountTypeIdentifier(ACAccountTypeIdentifierTwitter) 

     let callbackRequestAccess = { (granted: Bool, error: NSError!) -> Void in 
      ... 
      if(granted) { 
       callback() 
      } 

     } 

     accountStore.requestAccessToAccountsWithType(setAccountType, 
        options: nil, completion: callbackRequestAccess) 

    } 
} 

Welcome.swift

public class Welcome { 

    public func checkPermission() { 
     APIManager.getPermission(getTweet) 
    } 
    public func getTweet() { 
     ... 
    }   
} 

nie jestem pewien, że ten projekt w prawo czy nie. Nie chcę mieć silnego powiązania między tymi klasami, dlatego używam wywołania zwrotnego.

Czy to klasyczny wzór? Co więcej, nie mam ochoty takie zachowanie będzie łatwe do przetestowania?

Odpowiedz

7

Znacznie poprawisz testability, nie używając tutaj metod klasowych. Utwórz protokół TwitterConnection. Utwórz SystemTwitterConnection, który jest zgodny z nim i zarządza nim poprzez ACAccountStore. Utwórz TestTwitterConnection, który zwraca wstępnie ustawione odpowiedzi, które możesz skonfigurować do testowania. Możesz nawet utworzyć KeychainTwitterConnection, aby zarządzać loginami Twitter ręcznie, bez używania ACAccountStore, lub inną implementacją, jeśli Apple wyjdzie z jeszcze innym sposobem przechowywania tych kont.

Przekaż odpowiednie połączenie z Welcome po utworzeniu.

Jeżeli protokół TwitterConnection dostaje duże, należy zdecydowanie rozważyć podzielenie go na mniejsze protokołów, takich jak TwitterAuthenticator i TweetFetcher że obsłużyć mniej rzeczy (nawet jeśli jeden typ faktycznie realizuje wszystkich tych protokołów). Może to znacznie ułatwić testowanie, pozwalając typom testowym na implementację tylko kilku funkcji, a nie dziesiątek.

Stosowanie zamknięć jest prawdopodobnie w porządku, ale należy ściśle trzymać się konwencji nazewnictwa Cocoa. To, co nazywasz callback, jest tradycyjnie nazywane completion. Podążałbym też za przewodem Cocoa, jak nazwać metody. Zamiast getPermission(), będzie to requestAccessWithCompletionHandler(). Pomogłoby to rozmówcy zrozumieć, że ma ono bardzo podobne zachowanie do requestAccessToAccountsWithType(options:completion:). Nie buduj nowego słownictwa dla dzwoniącego.

1

https://en.wikipedia.org/wiki/Observer_pattern

To pomoże Ci oddzielić wydawcy zdarzeń (obserwowalnych) i konsumenta (obserwator).
Możesz również mieć specjalną obserwowalną implementację
, która nie łączy się z żadnym miejscem, ale powiadamia obserwatorów o zawartości statycznej.
W ten sposób można bezpośrednio wywołać metodę notifyObservers, do testowania zachowania obserwatorów.