State được sử dụng để triển khai phương thức hoạt động của một class tùy theo điều kiện
cụ thể. Trong State, object chủ thể không chứa code triển khai của các phương thức hoạt động
mà thay vào đó sẽ ủy thác tới các object State
tương ứng với các trạng thái khác nhau
của thực thể mà chúng ta muốn mô tả. State được xếp vào nhóm các pattern Hành Vi.
Áp dụng triển khai
Ở đây chúng ta có một ví dụ về phiên bản desktop của phần mềm quản lý một trang blog
nơi mọi người có thể đăng tải bài viết chia sẻ kiến thức. Sau khi người dùng đăng nhập và
bắt đầu tạo một bài viết mới rồi nhấn nút “Lưu lại”. Mặc định thì nút nhấn này sẽ lưu bài viết
ở trạng thái “Bản nháp” và chỉ đến khi người viết bài thực hiện thao tác chọn “Công khai”
thì bài viết mới được “Đăng tải”. Như bạn thấy thì chức năng “Lưu lại” lúc này có cách thức
hoạt động mang tính điều kiện và tùy thuộc vào trạng thái mà người dùng chọn để gắn nhãn
cho bài viết.
Về mặt triển khai trong phần mềm, object Post
mô tả thực thể là một bài viết được
người dùng tạo ra. Tính năng save()
của Post
sẽ không chứa mã triển khai hành động
thực thi cụ thể mà ủy thác cho các object State
tương ứng với 2 trạng thái: bản nháp Draft
và bài đã được đăng tải Published
.
Bước 1
Tạo class Post
mô tả thực thể bài viết và abstract State
.
statepattern/Post.java
packagestatepattern;publicclassPost{privateString title;privateString author;privateString body;privateState state;publicPost(){this.title ="";this.author ="";this.body ="";
state =newDraft();}publicStringgetTitle(){return title;}publicvoidsetTitle(String title){this.title = title;}publicStringgetAuthor(){return author;}publicvoidsetAuthor(String author){this.author = author;}publicStringgetBody(){return body;}publicvoidsetBody(String body){this.body = body;}publicStategetState(){return state;}publicvoidsetState(State state){this.state = state;}publicvoidsave(){
state.save(this);}publicStringtoString(){return"Bài viết: "+ title +"n"+"Tác giả: "+ author +"n"+"Trạng thái: "+ state.getName()+"n"+"Nội dung: "+ body;}}
statepattern/State.java
packagestatepattern;publicabstractclassState{protectedString name;publicState(String name){this.name = name;}publicabstractvoidsave(Post p);publicStringgetName(){return name;}}
Bước 2
Tạo 2 class trạng thái triển khai phương thức save()
.
statepattern/Draft.java
packagestatepattern;publicclassDraftextendsState{publicDraft(){super("Bản nháp");}@Overridepublicvoidsave(Post p){System.out.println("Bài viết: "+ p.getTitle()+" đã được lưu nháp.");}}
statepattern/Published.java
packagestatepattern;publicclassPublishedextendsState{publicPublished(){super("Đã đăng tải");}@Overridepublicvoidsave(Post p){System.out.println("Bài viết: "+ p.getTitle()+" đã được đăng tải.");}}
Bước 3
Viết code main
để kiểm tra hoạt động của các State
.
PatternDemo.java
importstatepattern.Post;importstatepattern.Published;publicclassPatternDemo{publicstaticvoidmain(String[] args){Post p =newPost();
p.setTitle("State Pattern");
p.setAuthor("Semi Art");
p.setBody("Coming soon...");
p.save();System.out.println("==============");System.out.println(p);System.out.println("==============");
p.setTitle("[Design Patterns] State Pattern");
p.setBody("State có nghĩa là trạng thái.");
p.setState(newPublished());
p.save();System.out.println("==============");System.out.println(p);}}
Bước 4
Kiểm chứng lại kết quả được in ra ở console
.
console
Bài viết:StatePattern đã được lưu nháp.==============Bài viết:StatePatternTác giả:SemiArtTrạng thái:Bản nháp
Nội dung:Coming soon...==============Bài viết:[DesignPatterns]StatePattern đã được đăng tải.==============Bài viết:[DesignPatterns]StatePatternTác giả:SemiArtTrạng thái: Đã đăng tải
Nội dung:State có nghĩa là trạng thái.
Nguồn: viblo.asia