Open mtchuyen opened 3 years ago
https://medium.com/@josueparra2892/flyweight-pattern-in-go-eb6c9342650
Flyweight is a structural design pattern that allows programs to support large numbers of objects while keeping memory usage low.
The pattern accomplishes this by sharing parts of the object’s state between multiple objects. In other words, the Flyweight saves RAM memory by caching the same information used by different objects.
https://betterprogramming.pub/7-code-patterns-in-go-i-cant-live-without-f46f72f58c4b
Facade tạm hiểu là mặt tiền. Facade Pattern là một trong những Pattern thuộc nhóm cấu trúc (Structural Pattern).
Mục đích của Facade Pattern là che giấu sự phức tạp của hệ thống con đằng sau. Thông qua Facade các hoạt động trở nên dễ dàng hơn.
It all boils down to the age-old software development principles: Keep It Simple, Stupid (KISS), and Don’t Repeat Yourself (DRY).
A facade hides the system's complexities and provides a simplified interface to the client.
Một Facade là một class cung cấp giao diện đơn giản cho hệ thống con cần tích hợp. Thông qua Facade tạo ra sự hạn chế tương tác với hệ thống con.
Facade thực sự phát huy tác dụng khi chúng ta cần tích hợp một hệ thống phức tạp vào mã nguồn của mình, nhưng thực sự chúng ta chỉ cần dùng 1 phần nhỏ trong hệ thống phức tạp đó.
Facade Pattern được dùng để các ứng dụng phía client dễ dàng giao tiếp với hệ thống. Thay vì phải làm việc với nhiều hệ thống/module con, Facade Pattern giúp ứng dụng client chỉ phải giao tiếp với 1 hệ thống duy nhất.
Ví dụ: Trên màn hình đăng ký, ta nhập thông tin như username, email… sau đó sang màn hình tiếp theo nhập địa chỉ (quận/huyện, phường/xã, đường, số nhà…) rồi sang màn hình tiếp để nhập các thông tin liên lạc như số điện thoại… Rõ ràng client sẽ phải tốn nhiều thời gian và thao tác không thân thiện. Với Facade Pattern, ta gộp tất các thông tin đó vào một màn hình, và client chỉ cần giao tiếp với màn hình đó thôi.
Giống như trong thực tế, khi bạn muốn mua 1 đôi giày trên trên sàn TMĐT như Tiki, Lazada, Shopee… Điều bạn cần làm là lựa chọn giày, đặt hàng, thanh toán và nhận hàng. Tất cả các hoạt động phức tạp phía sau đó bạn cũng không hề cần quan tâm. Các hoạt động như:
Rất nhiều hoạt động phức tạp diễn ra. Nhưng chúng ta hoàn toàn không cần quan tâm đến điều đó. Chúng ta chỉ cần quan tâm tới việc lên sàn TMĐT đặt hàng, và nhận hàng từ [shipper của sàn TMĐT]. Điều này có thể hiểu như là 1 ví dụ về Facade Pattern.
Lợi điểm là
Nhược điểm là
Façade Pattern tương tự với Adapter Pattern. Hai Pattern này làm việc theo cùng một cách, nhưng mục đích sử dụng của chúng khác nhau. Adapter Pattern chuyển đổi mã nguồn để làm việc được với mã nguồn khác. Nhưng Façade Pattern cho phép bao bọc mã nguồn gốc để nó có thể giao tiếp với mã nguồn khác dễ dàng hơn.
Abstract Factory có thể dùng như một giải pháp thay thế cho Facade khi bạn chỉ muốn ẩn cách các đối tượng hệ thống con được tạo ra khỏi code client.
Flyweight cho thấy cách tạo nhiều đối tượng nhỏ, trong khi Facade cho thấy cách tạo một đối tượng duy nhất đại diện cho toàn bộ hệ thống con.
Facade và Mediator có những công việc tương tự nhau: cố gắng tổ chức sự hợp tác giữa nhiều lớp được kết hợp chặt chẽ với nhau.
Một lớp Facade thường có thể được chuyển đổi thành Singleton vì một đối tượng facade duy nhất là đủ trong hầu hết các trường hợp.
Facade tương tự như Proxy ở chỗ cả hai đều đệm một thực thể phức tạp và tự khởi tạo nó. Không giống như Facade, Proxy có interface giống với đối tượng dịch vụ của nó, điều này làm cho chúng có thể hoán đổi cho nhau.
[Ref6]Here’s an example of how the Facade Pattern can be used in Golang:
package main
import (
"fmt"
)
type CPU struct{}
func (*CPU) Freeze() {
fmt.Println("CPU Freeze")
}
func (*CPU) Jump(position int) {
fmt.Printf("CPU Jump to %d\n", position)
}
func (*CPU) Execute() {
fmt.Println("CPU Execute")
}
type Memory struct{}
func (*Memory) Load(position int, data string) {
fmt.Printf("Memory Load data '%s' to position %d\n", data, position)
}
type HardDrive struct{}
func (*HardDrive) Read(position int, size int) string {
data := fmt.Sprintf("HardDrive Read data from position %d with size %d", position, size)
fmt.Println(data)
return data
}
type ComputerFacade struct {
cpu *CPU
memory *Memory
hardDrive *HardDrive
}
func NewComputerFacade() *ComputerFacade {
return &ComputerFacade{
cpu: &CPU{},
memory: &Memory{},
hardDrive: &HardDrive{},
}
}
func (c *ComputerFacade) Start() {
c.cpu.Freeze()
c.memory.Load(0, "boot_loader")
c.cpu.Jump(0)
c.cpu.Execute()
}
func main() {
computer := NewComputerFacade()
computer.Start()
}
In the example above, we have a ComputerFacade that provides a simplified interface to a set of subsystems such as CPU, Memory, and HardDrive.
[Ref7]
[Ref9]
https://quoeamaster.medium.com/golang-gotchas-1-singleton-pattern-9ea467f37436