Cơ bản về design pattern
Bài đăng này đã không được cập nhật trong 3 năm
Bài viết này mình viết dựa trên một số thứ mình tìm hiểu sau khi học 1 buổi workshop design pattern
Design pattern
Theo định nghĩa tại sourcemaking.com thì:
Là một giải pháp trung được sử dụng nhiều lần để giải quyết một vấn đề trong phát triển phần mềm. Sử dụng lại design pattern sẽ giúp hạn chế các vấn đề phát sinh và giúp code trong sáng, có hệ thống hơn
Các loại design pattern
Có 3 loai chinh đó là :
Creational design pattern
Là các design pattern thiên về khởi tạo các đối tượng
Structural design pattern
Là các design pattern cho phép ta định nghĩa các cách thức quan hệ giữa các đối tượng
Behavioral design pattern
Là các design pattern dùng trong việc thực hiện các hành vi của một đối tượng
Tiếp theo mình sẽ giới thiệu design pattern mình tìm hiểu được
Bridge pattern
Design pattern này được sử dụng khi ta muốn tách rời xử lý của một Class qua một Class khác. Giả sử ta có một lớp mà việc xử lý của nó quá phức tạp, ta muốn tách rời nó qua một lớp khác, ta sẽ chuyển các xử lý đó qua một lớp khác để có thể dễ dàng xử lý
Theo Bridge pattern thì mình đang có Abstraction là lớp Shape. RefinedAbstraction là 2 lớp Triangle và Circle Implementor là lớp Color ConcreteImplementor là lớp lớp GreenColor và BlueColor
Bình thường nếu ta muốn tô màu cho Triangle hoặc Circle, ta có thể nghĩ ngay đến việc implement hàm paint() trong Triangle và Circle như sau
public class Triangle extends Shape{
public void paint(color) {
// do something to fill color shape
}
}
Tuy nhiên việc implement hàm paint() như vậy sẽ khiến ta phải sửa lại code khi có thêm các loại Shape hoặc các Color khác.
Ở đây bridge pattern giúp ta giải quyết được một số vấn đề:
Abstraction và implementaion được định nghĩa một cách độc lập với nhau, giúp ta có thể dễ dàng quản lý, tái sử dụng code ... Mối quan hệ giữa abstraction và implementation được kiểm soát trong run-time code chứ không phải là compile code. Nếu ta để color là một thuộc tính của Shape thì mối quan hệ giữa chúng đã được xác định trong thời gian compile code.
Null object pattern
Mình thấy design pattern này có tư tưởng khá đơn giản. Nếu tìm được object thì trả về object đó, nếu không thì trả về một object khác có cùng interface behavior với real object. Trong ruby thì pattern này được sử dụng để tránh nil erorr khi gọi một hàm trên đối tượng nil
class User
attr_accessor :credit_card, :subscription
def charge
subscription.charge credit_card
end
def has_mentoring?
subscription.has_mentoring?
end
def price
subscription.price
end
def subscription
@subscription ||= NoSubscription.new
end
end
class NoSubscription
def charge credit_card
"No Charge"
end
def price
0
end
def has_mentoring?
false
end
end
Ở đây ta chú ý function subscription(). Nếu có subscription thì sẽ trả về @subscription, nếu không thì trả về một object NoSubscription mới.
Factory method
Tư tưởng của design pattern này là khởi tạo một đối tượng mà không cần biết trước chính xác lớp của đối tượng đó(creating objects without having to specify the exact class of the object that will be created).
public class Circle implements Shape {
public void draw() {
System.out.println("Circle");
}
}
public class Rectangle implements Shape {
public void draw() {
System.out.println("Shape");
}
}
public interface Shape {
void draw();
}
public class ShapeFactory {
public Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
}
Ở đây ta có thể khởi tạo Rectangle hoặc Circle mà không cần gọi Circle.new(). Đoạn code trong getShape() có if, else vi phạm quy tắc Open/Closed trong SOLID cần refactor lại một chút
All rights reserved