Chúng tôi thường sử dụng các bảng liệt kê đơn giản để thể hiện trạng thái trên các thực thể của chúng tôi. Vấn đề xảy ra khi chúng tôi giới thiệu hành vi phụ thuộc phần lớn vào trạng thái hoặc nơi chuyển đổi trạng thái phải tuân thủ các quy tắc kinh doanh nhất định.Mẫu trạng thái và thiết kế điều khiển tên miền
Lấy ví dụ sau đây (có sử dụng một điều tra để đại diện cho nhà nước):
public class Vacancy {
private VacancyState currentState;
public void Approve() {
if (CanBeApproved()) {
currentState.Approve();
}
}
public bool CanBeApproved() {
return currentState == VacancyState.Unapproved
|| currentState == VacancyState.Removed
}
private enum VacancyState {
Unapproved,
Approved,
Rejected,
Completed,
Removed
}
}
Bạn có thể thấy rằng lớp này sẽ sớm trở nên khá dài dòng như chúng ta thêm phương pháp để chối, Hoàn thành, Di chuyển, vv
Thay vào đó chúng ta có thể giới thiệu mô hình nhà nước, cho phép chúng tôi để đóng gói mỗi tiểu bang như một đối tượng:
public abstract class VacancyState {
protected Vacancy vacancy;
public VacancyState(Vacancy vacancy) {
this.vacancy = vacancy;
}
public abstract void Approve();
// public abstract void Unapprove();
// public abstract void Reject();
// etc.
public virtual bool CanApprove() {
return false;
}
}
public abstract class UnapprovedState : VacancyState {
public UnapprovedState(vacancy) : base(vacancy) { }
public override void Approve() {
vacancy.State = new ApprovedState(vacancy);
}
public override bool CanApprove() {
return true;
}
}
Điều này làm cho nó dễ dàng để chuyển betwee n bang, thực hiện logic trên cơ sở về tình trạng hiện tại hoặc thêm trạng thái mới nếu chúng ta cần phải:
// transition state
vacancy.State.Approve();
// conditional
model.ShowRejectButton = vacancy.State.CanReject();
đóng gói này có vẻ sạch hơn, nhưng nếu có đủ các quốc gia, những cũng có thể trở nên rất tiết. Tôi đọc Greg Young's post on State Pattern Misuse đề xuất sử dụng đa hình thay vì (vì vậy tôi sẽ có các lớp ApprovedVacancy, UnapprovedVacancy vv), nhưng không thể thấy cách này sẽ giúp tôi.
Tôi có nên ủy quyền chuyển tiếp trạng thái như vậy sang dịch vụ miền hoặc việc tôi sử dụng mẫu trạng thái trong tình huống này có đúng không?
nếu người tiêu dùng không nên thay đổi trạng thái trực tiếp chắc chắn điều này có nghĩa là tôi sẽ kết thúc bằng một phương pháp cho mỗi chuyển đổi trạng thái trên thực thể của tôi. Vì vậy, những gì tôi thực sự đạt được ở đây? –
Bạn nhận được đóng gói và sự vắng mặt của một loạt các tuyên bố nếu :) Đây là những lợi ích chính thức: 1. Nó địa phương hóa hành vi nhà nước cụ thể và hành vi phân vùng cho các tiểu bang khác nhau. 2. Nó làm cho trạng thái chuyển tiếp rõ ràng. 3. Các đối tượng nhà nước có thể được chia sẻ. –
Cảm ơn.Một câu hỏi cuối cùng - chúng tôi đang kiên trì Vị trí tuyển dụng vào một cửa hàng tài liệu (RavenDB). Bạn có gợi ý sử dụng để tải đối tượng trạng thái có liên quan hay chỉ lưu trữ toàn bộ đối tượng trạng thái –