Swift에서 프록시 패턴을 사용한 데이터 업데이트 로직

I 프록시 패턴을 사용한 데이터 업데이트 로직



디자인 패턴을 현실로 일어날 것 같은 사례를 참조하면서 학습하면, 단시간에 깊은 이해를 얻을 수 있다.

Swift에서 현실에 일어날 것 같은 상황을 소재로 한 Proxy Pattern의 예가 금방 발견되지 않았기 때문에 써 보았다.

이번은 사례를 바탕으로, 후술의 상황하에서 왜 Proxy Pattern이 유력한 실장 방법이 되는지를 설명.
그 후, 샘플 코드를 기재한다.

II 만들 시스템



요구사항


  • 화면을 열 때마다 서버 정보를로드하고 표시합니다.
  • 정보를로드하는 동안 사용자를 기다리지 마십시오
  • 표시되는 정보는 서버의 것에 비해 다소 오래 될 수 있습니다

  • 샘플



    Main Screen에서 왼쪽 상단의 "Contents"버튼을 누르면 컨텐츠 목록이 표시됩니다.
    콘텐츠의 일람 화면은, 표시될 때마다 서버로부터 UITableView에 표시하는 String형의 배열을 로드한다.


    III 프록시 패턴은 다른 구현보다 우수합니다.



    비 프록시 패턴에서는 타협이 발생합니다.



    먼저 프록시 패턴을 사용하지 않는 두 가지 구현을 소개합니다.
    이러한 방법을 사용하면 사용자를 기다릴 수 있으며 설계가 복잡해질 수 있습니다.
    문제가 있다.

    간단한 구현



    간단하고 간단하고 명쾌하지만 사용자를 기다리게하는 구현.

    ContentsTableViewController는, 열릴 때마다 Content Class로부터 새로운 정보의 취득을 요구한다.
    Content Class는 요청이있을 때마다 서버에 연결하여 정보를 검색하고 반환합니다.
    사용자는 서버로부터의 정보 취득이 완료 될 때까지 기다린다.


    복잡한 구현



    요구 사항을 충족하지만 설계가 복잡해질 수 있는 구현.

    App이 기동할 때마다 백그라운드로 데이터를 읽어들여, 유저가 ContantsTableViewController를 열었을 때에는, 벌써 데이터의 갱신이 완료되고 있도록(듯이) 하는 구현이 생각된다.

    이 방법은 상황에 따라 설계가 복잡해질 수 있습니다.

    프록시 패턴은 모든 약점을 극복



    프록시 패턴을 사용하면 위의 두 가지 문제를 해결할 수 있습니다.
    앞에서 설명한 "간단한 구현"에 ContentProxy 클래스를 추가하여 구현합니다.

    콘텐츠 프록시 클래스


  • 요청을 받으면 마지막 요청을 받았을 때의 정보를 반환합니다.
  • 동시에 백그라운드에서 Content Class에 액세스하여 정보를 얻고 다음에 저장합니다.


  • ContentProxy
    import UIKit
    
    class ContentProxy: NSObject, ContentProviding {
    
        let contentsSaveKey = "ContentsSaveKey"
    
        func getContents() -> AnyObject {
    
            let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
            dispatch_async(dispatch_get_global_queue(priority, 0)) {
    
                // 非同期処理で、次回アクセスされた時用のコンテンツをロード&保存
                let newContents = Content().getContents()
                NSUserDefaults.standardUserDefaults().setObject(newContents, forKey: self.contentsSaveKey)
    
            }
    
            // 前回(上記の非同期処理で)保存したコンテンツを返す。 NSUserDefaultsから取り出すので、ユーザーを待たせない。
            if let lastContents = NSUserDefaults.standardUserDefaults().objectForKey(self.contentsSaveKey) {
                return lastContents
    
            // 前回保存したコンテンツがない場合(Appの初回起動時など)はContent Classからコンテンツを取り出す。
            // Content Classgはサーバーから情報を取り出すので、このケースに限り、ユーザーを少し待たせることになる。
            } else {
                return Content().getContents()
            }
        }
    }
    

    사용자가 본 행동


  • 사용자가 볼 정보는 ContentsTableViewController를 열 때마다 업데이트됩니다.
  • 표시되는 정보는, 서버의 최신의 것이 아니고, 전회 액세스했을 때의 것.

  • IV 결론



    이번 방법은 요건으로 나타낸 바와 같이, 유저는 최신이 아니라 전회 컨텐츠 일람을 표시했을 때의 정보를 보게 된다.
    다만, 컨텐츠는 일람을 볼 때마다 갱신되기 때문에, 서버의 정보와 사용자에게 표시되는 정보를 시비어에 동기화하고 싶은 경우 이외에는, 설계를 단순하게 유지하기 때문에 유력한 후보가 될 수 있다.

    좋은 웹페이지 즐겨찾기