Baru-baru ini, saya lebih terlibat dalam pengembangan front-end daripada mobile, dan saya menemukan beberapa pola desain yang sangat menarik yang sudah saya ketahui, tetapi tidak benar-benar membahasnya ... sampai sekarang.
Tapi sekarang semua ini masuk akal, setelah menggunakan dari pengembangan React selama beberapa minggu, sekarang saya tidak bisa kembali ke cara lama saya mengembangkan untuk iOS. Saya tidak akan beralih ke javascript (AKA React Native) untuk mengembangkan aplikasi seluler, tetapi di sini ada beberapa hal yang saya pelajari.
Kembali ke pengembangan iOS, saya membuat proyek baru dan mulai menjelajahi
ReSwift , ini merupakan implementasi dari pola
Flux dan
Redux di Swift. Dan itu bekerja cukup sederhana, saya mengkloning arsitektur aplikasi JavaScript beberapa kali, sekarang saya memiliki keadaan global, dan pengendali saya hanya mendengarkan keadaan ini. Kontroler itu sendiri terdiri dari berbagai komponen presentasi yang merangkum perilaku yang sangat spesifik.

Semua perubahan
status dilakukan di satu tempat, dalam
peredam . Satu untuk media. Anda dapat melihat semua
tindakan di satu tempat. Tidak ada lagi kode jaringan atau pengendali panggilan, tidak ada lagi mutasi objek dalam tampilan. Tidak ada lagi kode spageti. Hanya ada satu
negara , dan itu benar, maka berbagai komponen presentasi Anda (dan saya bersikeras) berlangganan ke berbagai bagian
negara dan bereaksi sesuai. Ini hanyalah arsitektur terbaik untuk aplikasi model yang kuat.
Sebagai contoh. Sebelumnya, pengendali tampilan login dipenuhi dengan banyak baris kode, berbagai status kontrol, penanganan kesalahan, dll ... Sekarang terlihat seperti ini: (Sebagai contoh)
import UIKit import Base import ReSwift class LoginViewController: UIViewController { @IBOutlet var usernameField: UITextField! @IBOutlet var passwordField: UITextField! override func viewDidLoad() { super.viewDidLoad() store.subscribe(self) {state in state.usersState } } @IBAction func onLoginButton(_ sender: Any) { store.dispatch(AuthenticatePassword(username: usernameField.text!, password: passwordField.text!)) } @IBAction func onTwitterButton(_ sender: Any) { store.dispatch(AuthenticateTwitter()) } @IBAction func onFacebookButton(_ sender: Any) { store.dispatch(AuthenticateFacebook(from: self)) } }
Pengendali dan representasi tindakan
pengiriman di negara global, tindakan ini sebenarnya bekerja dengan jaringan atau meluncurkan berbagai bagian yang perlu dikonversi oleh aplikasi Anda ke negara baru.
Suatu tindakan dapat memicu tindakan lain, ini adalah bagaimana hal itu terjadi untuk permintaan jaringan, misalnya, Anda memiliki satu tindakan
FetchUser (id: String) dan satu tindakan yang Anda intersep dalam peredam yang terlihat seperti SetUser (pengguna: Pengguna). Dalam peredam, Anda bertanggung jawab untuk menggabungkan / menggabungkan objek baru dengan kondisi Anda saat ini.
Pertama Anda membutuhkan
status , contoh saya akan fokus di sekitar objek
Pengguna , jadi
status mungkin terlihat seperti ini:
struct UsersState { var users: [String: User] = [:] }
Anda harus memiliki file yang merangkum semua aktivitas jaringan untuk objek pengguna.
struct FetchUser: Action { init(user: String) { GETRequest(path: "users/\(user)").run { (response: APIResponse<UserJSON>) in store.dispatch(SetUser(user: response.object)) } } }
Segera setelah permintaan selesai, ia memanggil
tindakan lain, tindakan ini sebenarnya kosong, harus dirujuk, misalnya, di UsersActions. Tindakan ini menjelaskan hasil yang harus diandalkan peredam untuk mengubah status.
struct SetUser: Action { let user: UserJSON? }
Dan akhirnya, pekerjaan yang paling penting dilakukan di
UsersReducer , Anda perlu menangkap tindakan dan melakukan beberapa pekerjaan sesuai dengan isinya:
func usersReducer(state: UsersState?, action: Action) -> UsersState { var state = state ?? initialUsersState() switch action { case let action as SetUser: if let user = action.user { state.users[user.id] = User(json: user) } default: break } return state }
Sekarang semua yang diperlukan adalah
suscribe / berlangganan negara dalam pengontrol atau tampilan, dan ketika itu berubah, ekstrak informasi yang diperlukan dan dapatkan nilai-nilai baru!
class UserViewController: UIViewController { var userId: String? { didSet { if let id = userId { store.dispatch(FetchUser(user: id)) } } } var user: User? { didSet { if let user = user { setupViewUser(user: user) } } } override func viewDidLoad() { super.viewDidLoad() store.subscribe(self) {state in state.usersState } } func setupViewUser(user: User) {
Tetapi sekarang Anda harus melihat contoh
ReSwift untuk pemahaman yang lebih dalam, saya berencana untuk menerbitkan aplikasi open source (sebenarnya sebuah game) menggunakan pola desain ini. Tetapi untuk sekarang, kode ini menampilkan ide yang sangat kasar tentang bagaimana semua ini bekerja bersama.
Ini masih merupakan arsitektur yang sangat awal dalam buku Glose, tetapi kami tidak sabar menunggu aplikasi untuk diproduksi menggunakan arsitektur ini.
Saya merasa bahwa mengembangkan aplikasi menggunakan pola ini akan menghemat banyak waktu dan tenaga. Dibutuhkan lebih banyak pekerjaan daripada
klien REST yang bodoh dan sederhana, karena akan ada sedikit lebih banyak logika di dalam status klien, tetapi pada akhirnya itu akan menghemat waktu Anda yang tak ternilai untuk debugging. Anda akan dapat memodifikasi banyak elemen secara lokal, dan tidak akan ada lagi perubahan cascading antara pengontrol dan tampilan. Mereproduksi keadaan dalam urutan cadangan, mengarsipnya, membuat middleware, dll. Aliran data aplikasi jelas, terpusat, dan sederhana.
Pola
Redux menambahkan sedikit struktur ke aplikasi. Saya telah melakukan MVC murni untuk waktu yang sangat lama, saya yakin Anda dapat membuat basis kode yang bersih, tetapi Anda cenderung mengembangkan kebiasaan yang sering kali lebih berbahaya daripada baik. Anda bahkan dapat mengambil langkah lebih jauh dan sepenuhnya mengimplementasikan Redux dengan mengendalikan antarmuka pengguna Anda (seperti pengontrol tampilan, pengamat peringatan, pengontrol perutean) dalam keadaan terpisah, tapi saya belum mencapai semua ini).
Dan pengujiannya ... Pengujian unit sekarang mudah diimplementasikan, karena yang perlu Anda uji adalah membandingkan data yang Anda masukkan dengan data yang terkandung dalam keadaan global, sehingga tes dapat mengirim tindakan tiruan, dan kemudian memeriksa apakah negara cocok dengan apa yang Anda mau.
Serius, ini masa depan. Masa depan adalah untuk
Redux :)