/ / Triển khai State Pattern trong TypeScript

Triển khai State Pattern trong TypeScript

Mẫu thiết kế là một mẫu giải quyết một vấn đề thường lặp lại trong thiết kế phần mềm.


Mẫu trạng thái là một mẫu hành vi cho phép một đối tượng thay đổi hành vi của nó khi trạng thái bên trong của nó thay đổi.

Ở đây bạn sẽ học cách sử dụng mẫu trạng thái trong TypeScript.


Mô hình trạng thái là gì?

Mẫu thiết kế trạng thái có liên quan chặt chẽ đến một máy trạng thái hữu hạn, mô tả một chương trình tồn tại trong một có hạn số trạng thái tại bất kỳ thời điểm nhất định nào và hoạt động khác nhau trong mỗi trạng thái.

Có các quy tắc giới hạn, được xác định trước — chuyển tiếp — chi phối các trạng thái khác mà mỗi trạng thái có thể chuyển sang.

Đối với ngữ cảnh, trong một cửa hàng trực tuyến, nếu đơn đặt hàng mua sắm của khách hàng đã được “giao”, thì không thể “hủy” vì đơn đặt hàng đã được “giao”. “Đã giao” và “Đã hủy” là các trạng thái hữu hạn của đơn đặt hàng và đơn đặt hàng sẽ hoạt động khác nhau dựa trên trạng thái của nó.

Mẫu trạng thái tạo ra một lớp cho mỗi trạng thái có thể, với hành vi dành riêng cho trạng thái được chứa trong mỗi lớp.

Một ứng dụng dựa trên tiểu bang mẫu

Ví dụ: giả sử bạn đang tạo một ứng dụng theo dõi trạng thái của một bài báo cho một công ty xuất bản. Một bài báo có thể đang chờ phê duyệt, do một nhà văn soạn thảo, một biên tập viên chỉnh sửa hoặc xuất bản. Đây là những trạng thái hữu hạn của một bài báo sẽ được xuất bản; trong mỗi trạng thái duy nhất, bài viết hoạt động khác nhau.

Bạn có thể hình dung các trạng thái và quá trình chuyển đổi khác nhau của ứng dụng bài viết với biểu đồ trạng thái bên dưới:

Triển khai kịch bản này trong mã, trước tiên bạn phải khai báo một giao diện cho Bài viết:

interface ArticleInterface {
pitch(): void;
draft(): void;
edit(): void;
publish(): void;
}

Giao diện này sẽ có tất cả các trạng thái có thể có của ứng dụng.

Tiếp theo, tạo một ứng dụng triển khai tất cả các phương thức giao diện:


class Article implements ArticleInterface {
constructor() {
this.showCurrentState();
}

private showCurrentState(): void {
}

public pitch(): void {
}

public draft(): void {
}

public edit(): void {
}

public publish(): void {
}
}

Tư nhân showCurrentState method là một phương thức hữu ích. Hướng dẫn này sử dụng nó để hiển thị những gì xảy ra trong mỗi trạng thái. Nó không phải là một phần bắt buộc của mẫu trạng thái.

Xử lý chuyển đổi trạng thái

Tiếp theo, bạn sẽ cần xử lý các chuyển đổi trạng thái. Xử lý chuyển đổi trạng thái trong lớp ứng dụng của bạn sẽ yêu cầu nhiều câu lệnh điều kiện. Điều này sẽ dẫn đến mã lặp lại khó đọc và khó duy trì hơn. Để giải quyết vấn đề này, bạn có thể ủy thác logic chuyển tiếp cho mỗi trạng thái cho lớp riêng của nó.

Trước khi bạn viết mỗi lớp trạng thái, bạn nên tạo một lớp cơ sở trừu tượng để đảm bảo bất kỳ phương thức nào được gọi trong trạng thái không hợp lệ đều có lỗi.

Ví dụ:

abstract class ArticleState implements ArticleInterface {
pitch(): ArticleState {
throw new Error("Invalid Operation: Cannot perform task in current state");
}

draft(): ArticleState {
throw new Error("Invalid Operation: Cannot perform task in current state");
}

edit(): ArticleState {
throw new Error("Invalid Operation: Cannot perform task in current state");
}

publish(): ArticleState {
throw new Error("Invalid Operation: Cannot perform task in current state");
}
}

Trong lớp cơ sở ở trên, mọi phương thức đều có lỗi. Bây giờ, bạn phải ghi đè từng phương thức bằng cách tạo các lớp cụ thể kéo dài lớp cơ sở cho mỗi trạng thái. Mỗi lớp cụ thể sẽ chứa logic trạng thái cụ thể.

Mỗi ứng dụng có một trạng thái nhàn rỗi, trạng thái này sẽ khởi tạo ứng dụng. Trạng thái nhàn rỗi cho ứng dụng này sẽ đặt ứng dụng thành dự thảo tiểu bang.

Ví dụ:

class PendingDraftState extends ArticleState {
pitch(): ArticleState {
return new DraftState();
}
}

Các sân bóng đá phương thức trong lớp trên khởi tạo ứng dụng bằng cách đặt trạng thái hiện tại thành DraftState.

Tiếp theo, ghi đè phần còn lại của các phương thức như sau:

class DraftState extends ArticleState {
draft(): ArticleState {
return new EditingState();
}
}

Mã này ghi đè dự thảo và trả về một phiên bản của E EditState.

class EditingState extends ArticleState {
edit(): ArticleState {
return new PublishedState();
}
}

Khối mã ở trên ghi đè chỉnh sửa và trả về một phiên bản của Đã xuất bản.

class PublishedState extends ArticleState {
publish(): ArticleState {
return new PendingDraftState();
}
}

Khối mã ở trên ghi đè công bố và đưa ứng dụng trở lại trạng thái nhàn rỗi, PendingDraftState.

Sau đó, bạn cần cho phép ứng dụng thay đổi trạng thái của nó trong nội bộ bằng cách tham chiếu trạng thái hiện tại thông qua một biến private. Bạn có thể thực hiện việc này bằng cách khởi tạo trạng thái nhàn rỗi bên trong lớp ứng dụng của mình và lưu trữ giá trị vào một biến private:

private state: ArticleState = new PendingDraftState();

Tiếp theo, cập nhật showCurrentState phương thức để in giá trị trạng thái hiện tại:

private showCurrentState(): void {
console.log(this.state);
}

Các showCurrentState phương thức ghi lại trạng thái hiện tại của ứng dụng vào bảng điều khiển.

Cuối cùng, gán lại biến private cho thể hiện trạng thái hiện tại trong mỗi phương thức của ứng dụng của bạn.

Ví dụ: cập nhật các ứng dụng của bạn sân bóng đá phương thức cho khối mã bên dưới:

public pitch(): void {
this.state = this.state.pitch();
this.showCurrentState();
}

Trong khối mã ở trên, sân bóng đá phương thức thay đổi trạng thái từ trạng thái hiện tại sang trạng thái cao độ.

Tương tự, tất cả các phương thức khác sẽ thay đổi trạng thái từ trạng thái ứng dụng hiện tại sang trạng thái tương ứng của chúng.

Cập nhật các phương pháp ứng dụng của bạn cho các khối mã bên dưới:

Các dự thảo phương pháp:

public draft(): void {
this.state = this.state.draft();
this.showCurrentState();
}

Các chỉnh sửa phương pháp:

public edit(): void {
this.state = this.state.edit();
this.showCurrentState();
}

công bố phương pháp:

public publish(): void {
this.state = this.state.publish();
this.showCurrentState();
}

Sử dụng ứng dụng đã hoàn thành

Lớp ứng dụng đã hoàn thành của bạn phải tương tự như khối mã bên dưới:


class Article implements ArticleInterface {
private state: ArticleState = new PendingDraftState();

constructor() {
this.showCurrentState();
}

private showCurrentState(): void {
console.log(this.state);
}

public pitch(): void {
this.state = this.state.pitch();
this.showCurrentState();
}

public draft(): void {
this.state = this.state.draft();
this.showCurrentState();
}

public edit(): void {
this.state = this.state.edit();
this.showCurrentState();
}

public publish(): void {
this.state = this.state.publish();
this.showCurrentState();
}
}

Bạn có thể kiểm tra các chuyển đổi trạng thái bằng cách gọi các phương thức theo đúng trình tự. Ví dụ:

const docs = new Article(); 

docs.pitch();
docs.draft();
docs.edit();
docs.publish();

Khối mã ở trên hoạt động vì các trạng thái của ứng dụng đã chuyển đổi một cách thích hợp.

Nếu bạn cố gắng thay đổi trạng thái theo cách không được phép, chẳng hạn như từ trạng thái cao độ sang trạng thái chỉnh sửa, ứng dụng sẽ báo lỗi:

const docs = new Article(); 
docs.pitch()
docs.edit()

Bạn chỉ nên sử dụng mẫu này khi:

  • Bạn đang tạo một đối tượng hoạt động khác nhau tùy thuộc vào trạng thái hiện tại của nó.
  • Đối tượng có nhiều trạng thái.
  • Hành vi của tiểu bang cụ thể thay đổi thường xuyên.

Ưu điểm và Đánh đổi của Mô hình Nhà nước

Mô hình này loại bỏ các câu lệnh điều kiện cồng kềnh và duy trì trách nhiệm duy nhất và các nguyên tắc mở / đóng. Nhưng nó có thể quá mức cần thiết nếu ứng dụng có ít trạng thái hoặc các trạng thái của nó không đặc biệt năng động.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *