Trong bài viết này chúng ta sẽ cùng nhau tìm hiểu về Facade design pattern sử dụng ngôn ngữ Scala
Mục đích
- Cung cấp một interface thống nhất cho tập hợp các interface trong hệ thống con. Facade cung cấp một interface ở lớp cao hơn giúp cho hệ thống con dễ sử dụng hơn.
- Đóng gói một hệ thống con với một interface đơn giản hơn
Facade design pattern là gì?
Facade design pattern là một structural design pattern và thường được sử dụng trong OOP
Facade design pattern thường được Developer sử dụng khi hệ thống trở nên phức tạp hoặc khó hiểu hoặc khi hệ thống có số lượng lớn các class phụ thuộc lẫn nhau hoặc có thể khi source code không thể dùng được
Pattern này giúp ẩn đi hệ thống lớn phức tạp và cung cấp một interface đơn giản cho phía client
Client giao tiếp với hệ thống con bằng cách gửi các yêu cầu đến Facade, Facade sẽ dịch và xử lý giao tiếp giữa các hệ thống con.
Facade có thể được sử dụng để tạo lớp bằng cách tách rời các hệ thống con. Các chức năng của một Facade cụ thể giống như một điểm vào các hệ thống con mà nó đóng gói
Việc sử dụng Facade như một điểm vào thúc đẩy sự liên kết yếu giữa các thành phần hệ thống con và cho phép bạn thay đổi các thành phần mà không ảnh hưởng đến client.
Biến các class của các hệ thống con thành private sẽ hữu ích, nhưng rất ít ngôn ngữ hướng đối tượng hỗ trợ nó
Các object của Facade thường là Singleton
Ví dụ
Chúng ta thường có một chuyến du lịch cho công ty đến các thành phố và để tổ chức nó, chúng ta thường hỏi các đại lý du lịch và yêu cầu họ cung cấp giá hiện hành. Bảng báo giá của họ thường dựa trên các yếu tố như là thể loại (nhóm, gia đình, trăng mật) và các gói (vàng, bạc, đồng).
Dựa trên các cơ sở trên để lựa chọn, quá trình đặt tour được bắt đầu và họ sẽ sử dụng một ứng dụng quản lý tour.
Ứng dụng này gồm các hệ thống con như là
- Đặt vé (TicketBooking)
- Đặt khách sạn (HotelBooking)
- Đặt các phương tiện để đi tham quan (ShuttleBooking)
- Đặt hướng dẫn viên du lịch (GuideBooking)
Để sử dụng các hệ thống con này, client có thể tương tác trực tiếp với nó. Nhưng có một vấn đề với cách tiếp cận này ví dụ như nếu có bất kỳ thay đổi nào trong hệ thống con như là thêm/ sửa/ xoá của Service mới trong hệ thống con, thì chúng ta sẽ phải thay đổi ứng dụng client, nó không phải là cách tiếp cận tốt
Giải pháp
Chúng ta sẽ tạo một Facade class như một interface giữa client và các hệ thống con. Với thiết kế này, client sẽ tương tác với Facade và Facade class sẽ tương tác với các hệ thống con thay vì client tương tác trực tiếp tới các hệ thống con
Source code
Client.scala
package app import facade.TourAndTravelFacade object Client extends App { val facade = new TourAndTravelFacade val tourPackage = "Platinum" val destination = "Udaipur" val departure = "Delhi" facade.bookHolidayPackage(tourPackage, destination, departure) }
TourAndTravelFacade.scala
package facade import subsystems.{ShuttleBooking, GuideBooking, HotelBooking, TicketBooking} class TourAndTravelFacade { val ticketBooking = new TicketBooking val hotelBooking = new HotelBooking val cabBooking = new ShuttleBooking val guideBooking = new GuideBooking def bookHolidayPackage(tourPackage : String, destination : String, departure : String) : Boolean = { ticketBooking.bookFlight(tourPackage, destination, departure) hotelBooking.bookHotel(tourPackage, destination) cabBooking.bookShuttle(tourPackage) guideBooking.bookGuide(destination) true } }
TicketBooking.scala
package subsystems class TicketBooking { def bookFlight(tourPackage : String, destination : String, departure : String) : Unit = { println("Round Trip Flight tickets for " + destination + " & " + departure + " is booked under package " + tourPackage) } }
HotelBooking.scala
package subsystems class HotelBooking { def bookHotel(tourPackage : String, destination : String) : Unit = { println("Hotel booked at " + destination+ " under package " + tourPackage) } }
ShuttleBooking.scala
package subsystems class ShuttleBooking { def bookShuttle(tourPackage : String) : Unit = { println("Shuttle is booked under package " + tourPackage) } }
GuideBooking.scala
package subsystems class GuideBooking { def bookGuide(destination : String) : Unit = { println("A guide is booked for sightseeing at " + destination) } }
Kết quả
Round Trip Flight tickets for Udaipur & Delhi is booked under package Platinum Hotel booked at Udaipur under package Platinum Shuttle is booked under package Platinum A guide is booked for sightseeing at Udaipur