Loading...

Merhaba, hazırlamış olduğum bu yazıda VIPER mimarisinin ne olduğu, neden tercih edilmesi gerektiği, avantajları ve dezavantajları hakkında bilgilere yer verdim.

VIPER Nedir?

VIPER, uygulamamızı bir modül içerisinde, farklı özelliklere sahip beş katmana ayıran bir mimaridir. Her bir katmanın ayrı bir rolü bulunmaktadır. Bunları aşağıdaki gibi özetleyebiliriz:

View: View, çoğu zaman dokunma olaylarını alan dummy bir nesnedir. MVC’nin binlerce kod satırı içeren devasa ViewController’ı yerine, yapılacak işlemler ile ilgili tüm kodlar ve karar verme işlemleri View’de bulunmamalıdır. Örneğin, kullanıcıdan bir dokunma işlemi alındığında, View nesnesi Presenter’a bu durumu bildirmelidir.

Interactor: Interactor business logic içerir. Ve çoğunlukla API çağrılarından sorumludur. Bu katmanda yapılan işlemler UI dan bağımsız olarak gerçekleşir.

Presenter: Presenter, bu mimarinin merkezindeki katman diyebiliriz. Diğer katmanlarla haberleşmeyi sağlar. Bütün kararlar presenter katmanında ele alınır. View’dan gelen bildirimleri alır ve onlarla ne yapılacağına karar verir. Örneğin, Interactor’dan bazı veriler isteyebiliriz veya Router’a farklı bir ekrana yönlenmesini söyleyebiliriz. Presenter ayrıca, Interactor’dan veriler alır ve komutlarla View’a iletir.

Entity: Entity, Interactor tarafından yönlendirilen veri objeleridir. 

Router: Router’ın işi ekranlar arasında yönlenmeyi sağlamaktır. Yalnızca Presenter’ı tanır ve ondan komutlar alır.

VIPER Mimarisi

İşleyiş

  • View, Presenter ile haberleşir. Kullanıcının gerçekleştirdiği aksiyonu Presenter’a iletir. Presenter’dan gelen cevaba göre işlemi gerçekleştirir.
  • Interactor, Presenter ile haberleşir. Servis ile haberleşme de Interactor’da yapılır.
  • Router, presenter ile haberleşir. Ve ekran yönlenmeleri sadece Router’da yapılır.
  • Katmanlar arası Protocol’ler ile iletişim kurulması sağlanır.

Projemiz büyüdüğünde binlerce satıra sahip ViewContoller olması durumunda, global değişkenlerin gittikçe artması ve uygulamayı debug etmenin gittikçe zorlaşması durumunda VIPER tasarım desenini tercih edebiliriz.

Avantajlar

  • Her bir nesnenin tek bir rolü olması
  • Veri akışının kolay takip edilebilmesi
  • Büyük projelerde hata ayıklamanın kolay olması ve test kolaylığı

Dezavantajlar

  • Küçük projelerde karmaşık olması
  • Yeni bir geliştiricinin VIPER’ ın temellerini öğrenmesi için normalden fazla zaman harcaması gerekmesi

Örnek Uygulamaya Giriş

Uygulamamız ekranda ‘Hello VIPER’ metni göstermek üzerine kurgulandı. Öncelikle projemizi oluşturup katmanlarımızı hazır hale getirmeliyiz. Aşağıdaki gibi bir klasörleme  yapısı oluşturabiliriz.

Klasörleme Yapısı

Presenter’ı mimarinin merkezinde düşünebiliriz. Böylece yapı kafamızda daha rahat canlanabilir. Entity hariç her bir katmanın Protocol’ü bulunur. Bu protocol’ler ile katmanlar arası iletişim kurulur.

Protocol’ler oluşturulduktan sonra hangi katmanla iletişim kurulması gerektiği göz önünde bulundurularak her katman ile ilgili değişkenler tanımlanır.

Ardından, Modül oluşturma methodu yazmamız gerekmektedir. Genel kullanım olarak; farklı modüller Router ile iletişim kurduğu için bu methodu Router içerisine yazmamız daha uygun olacaktır.

HomeRouter.swift

“createModule” fonksiyonu yukarıda bahsedildiği gibi Router içerisinde oluşturuldu.

import UIKit

protocol HomeRouterInterface {
    
}

class HomeRouter {
    func createModule() -> UIViewController {
        let view = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
        let interactor = HomeInteractor()
        let router = HomeRouter()
        let presenter = HomePresenter(view: view, interactor: interactor, router: router)
        view.presenter = presenter
        return view
    }
}

extension HomeRouter: HomeRouterInterface {
    
}

HomeRouter.swift

ViewController’da Label oluşturuldu, updateTitle fonksiyonu yazıldı. Burada amaç Interactor içerisinde oluşturulan getTitle methodunun nasıl çalıştığını görüp ardından updateTitle methodundan gelen değerin ekrana nasıl basıldığını görmek.

HomeViewController.swift  

import UIKit

protocol HomeViewControllerInterface: class {
    func updateTitle()
}

class HomeViewController: UIViewController {
    
    @IBOutlet var helloLabel: UILabel!
    var presenter: HomePresenterInterface!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.presenter.viewDidLoad()
        
    }
}

extension HomeViewController: HomeViewControllerInterface {
    func updateTitle() {
        helloLabel.text = "Hello VIPER"
    }
}

HomeViewController.swift

HomePresenter.swift

import UIKit

protocol HomePresenterInterface {
    func viewDidLoad()
}

class HomePresenter {
    weak var view: HomeViewControllerInterface?
    var interactor: HomeInteractorInterface
    var router: HomeRouterInterface
    
    init(view: HomeViewControllerInterface, interactor: HomeInteractorInterface, router: HomeRouterInterface) {
        self.view = view
        self.interactor = interactor
        self.router = router
    }
}

extension HomePresenter: HomePresenterInterface {
    func viewDidLoad() {
        let homeModel = self.interactor.getTitle()
        print("Home Model value is \(homeModel)")
        view?.updateTitle()
    }
}

HomePresenter.swift

View, Presenter ile haberleştiği için View içerisinde presenter değişkeni oluşturuldu. 

Presenter içerisinde View’da bulunan viewDidLoad fonksiyonu eklendi. Ayrıca view, router ve interactor değişlenleri tanımlandı.

– Ekran açıldığında viewDidLoad çalışacak presenter’a gidilecek. 

– Presenter’da kullanıcıya gösterilecek title için getTitle ve updateTitle methoduna gidilecek. getTitle methodu Interactor’da tanımlanmıştır. Title’ın ne olacağı ilk olarak Interactor’da belirlenmiştir.

– Presenter Interactor’da oluşturulan title değerini alacak ardından bunu çağıracak.

– Title ın nasıl güncellendiğini görebilmemiz için de Presenter updateTitle methodunu çağıracak. Ve ekranda ne yazacağını View’a haber verecek. Router da hangi ekrana yönlenileceğini belirleyecek.

– Son olarak Presenter tüm bu bilgileri View’a haber verecek ve kullanıcı ekranda verilen mesajı görebilecek.

HomeInteractor.swift

import Foundation

protocol HomeInteractorInterface {
    func getTitle() -> HomeModel
}

class HomeInteractor { }

extension HomeInteractor: HomeInteractorInterface {
    func getTitle() -> HomeModel {
        return HomeModel(title: "Home VIPER")
    }
}

HomeInteractor.swift

HomeModel.swift

struct HomeModel {
    
    let title: String
}

AppDelegate.swift dosyasındaki application fonksiyonunun içerisine aşağıdaki gibi tanımlamamızı yapıyoruz. Uygulama açıldığında gösterilecek olan ViewController’ ımızın hangisi olacağını burada belirtiyoruz.

self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = HomeRouter().createModule()
self.window?.makeKeyAndVisible()

Sonuç

GetTitle methoduyla; title ‘Home VIPER’ olarak alınmıştır.

updateTitle methodu çağırıldığında; title ‘Hello VIPER’ olmuştur.

Output

One thought on “VIPER’a Giriş”

    avatar

    Tebrik ederim Gamze güzel yazı olmuş. Devamını beklerim.

    25/03/2020- Cevapla