Behavior parameterization
được hiểu là dựa vào hành vi ngừoi dùng để tạo ra tham số cho các hàm.
Nếu bạn nào đã từng tìm hiểu qua Behavior Driver Development
phát triển phần mềm dựa trên nền tảng hành vi ngừoi dùng.
Trong quá trình làm phần mềm, các yêu cầu thiết kế thay đổi liên tục để tạo ra sản phẩm mà ngừoi dùng hài lòng nhất.
Behavior parameterization
là một cách viết code như vậy, và trong Java 8 có hỗ trợ chúng ta viết code theo cách này rất hay. Thông qua bài này mình giới thiệu cách mình hiều về nó.
Ví dụ
Nếu bạn có một bộ sưu tập [Collection] là một rổ táo
- Lúc đầu yêu cầu thiết kế chỉ là lấy ra những quả táo có màu xanh
- Tiếp theo yêu cầu thay đổi là lấy những quá táo có mày xanh và nặng hơn 150 gram.
- và yêu cầu tiếp tục thay đổi mở rộng theo thời gian và theo nhu cầu từ ngừoi dùng.
- …
1. Thục hiện yêu cầu ban đầu
public static List<Apple> filterGreenApple(List<Apple> inventory){
List<Apple> result = new ArrayList<>();
for (Apple apple : inventory){
if ("green".equals(apple.getColor())){
result.add(apple);
}
}
return result;
}
Cách sử dụng là:
List<Apple> greenApples = filterGreenApple(inventory)
Vấn đề có thấy là nếu muốn filter những quả táo có màu đỏ
thì sao, và những màu khác nữa thì sao???
2. Thêm tham số color
public static List<Apple> filterByColor(List<Apple> inventory, String color){
List<Apple> result = new ArrayList<>();
for (Apple apple : inventory){
if (color.equals(apple.getColor())){
result.add(apple);
}
}
return result;
}
Cách sử dụng là:
List<Apple> greenApples = filterGreenApple(inventory, "green")
List<Apple> greenApples = filterGreenApple(inventory, "red")
Bằng cách để ý tới hành vi có khả năng phát sinh trong tương lai chúng ta đã tạo ra một hàm có tính cơ động hơn rất nhiều.
Tiếp theo là yêu cầu bổ sung thêm trọng lượng lớn hơn 150 gram. Lúc này chúng ta áp dụng lại cách đã làm ở bước số 2, chúng ta mở rộng thành hỗ trợ lọc tất cả các thuộc tính của 1 quả táo
mà không chỉ là thêm cân nặng.
3. Support filter by all attributes
Step 1: Đầu tiên định nghĩa đối tượng Quả táo
:
@Getter
public class Apple {
private String color;
private int weight;
}
Step 2: Tiếp theo là tạo một phương thức kiểm tra/dự đoán thuộc tính của 1 qua táo Predicate
public interface ApplePredicate {
boolean test(Apple apple);
}
Step3: Tạo Stategy
để lọc theo thuộc tính màu sắc color
:
public class AppleColorPredicate implements ApplePredicate{
@Override
public boolean test(Apple apple) {
return apple.getColor().equals("green");
}
}
Step 4: Tạo Stategy
để lọc theo thuộc tính cân nặng weight
:
public class AppleWeightPredicate implements ApplePredicate {
@Override
public boolean test(Apple apple) {
return apple.getWeight() >150;
}
}
Step 5: Tạo một hàm filter khái quát:
public static List<Apple> filterApple(List<Apple> inventory,ApplePredicate p ){
List<Apple> result = new ArrayList<>();
for (Apple apple : inventory){
if (p.test(apple)){
result.add(apple);
}
}
return result;
}
Step 6: Hàm hành vi :
public static void main(String[] args) {
List<Apple> inventory = new ArrayList<>();
List<Apple> readApples = inventory
.stream()
.filter(apple -> "red".equals(apple.getColor()))
.filter(apple -> apple.getWeight()>150)
.collect(Collectors.toList());
}