Present delegate-state
Transcript of Present delegate-state
Delegate pa)ern State pa)ern
Giang Minh
Outline
• Delegate – Bài toán, vấn đề – Giới thiệu delegate và áp dụng – Các trường hợp nên sử dụng
• State – Bài toán thực tế – Vấn đề khi giải quyết bằng phương pháp thông thường
– Các giải quyết với state
Bài toán
• Slidemenu
Bài toán
• Slidemenu
Bài toán
• Slidemenu
Bài toán
• Vấn đề – Cùng một dạng nhưng được lặp lại • Có một vài hành vi khác nhau
• Thông thường – Dư thừa code – Không sử dụng lại được code
Delegate pattern
•
Hoàn cảnh sử dụng
• Giảm thiểu sự móc nối các func^on giữa các class
• Có những thành phần cố định – Nhưng hành vi thay đổi tuỳ ngữ cảnh
Nhận xét
• Điểm mạnh – Reuse – Mềm dẻo
• Điểm yếu – Tốn công – Khi cần phản hồi đến nhiều delegator
Bài toán 2
• Nhân vật trong game có hành động – Nhảy khi ấn phím B
Bài toán 2
• Nhân vật trong game có hành động – Nhảy khi ấn phím B
void Heroine::handleInput(Input input) { if (input == PRESS_B) { yVelocity_ = JUMP_VELOCITY; setGraphics(IMAGE_JUMP); } }
Bài toán 2
• Nhân vật trong game có hành động – Nhảy khi ấn phím B
– Vấn đề????
void Heroine::handleInput(Input input) { if (input == PRESS_B) { yVelocity_ = JUMP_VELOCITY; setGraphics(IMAGE_JUMP); } }
Sửa bug1
• -‐> OK • Muốn thêm động tác ngồi???
void Heroine::handleInput(Input input){ if (input == PRESS_B){ if (!isJumping_){ isJumping_ = true; // Jump... }
Thêm trạng thái
• Thêm if
• Any problem??
void Heroine::handleInput(Input input){ if (input == PRESS_B) { // Jump if not jumping... } else if (input == PRESS_DOWN){ if (!isJumping_) { setGraphics(IMAGE_DUCK); } } else if (input == RELEASE_DOWN) { setGraphics(IMAGE_STAND); } }
Thêm trạng thái
• Thêm if
• Any problem?? – Ngồi -‐> ấn nhảy, thả phím down -‐> đứng dậy trên không
void Heroine::handleInput(Input input){ if (input == PRESS_B) { // Jump if not jumping... } else if (input == PRESS_DOWN){ if (!isJumping_) { setGraphics(IMAGE_DUCK); } } else if (input == RELEASE_DOWN) { setGraphics(IMAGE_STAND); } }
Sửa bug2
• Thêm checker void Heroine::handleInput(Input input){ if (input == PRESS_B) { if (!isJumping_ && !isDucking_) { // Jump... } } else if (input == PRESS_DOWN) { if (!isJumping_) { isDucking_ = true; setGraphics(IMAGE_DUCK); } } else if (input == RELEASE_DOWN) { if (isDucking_){ isDucking_ = false; setGraphics(IMAGE_STAND); } } }
Thêm chức năng
• Tấn công khi đang nhảy và ấn DOWN
Thêm chức năng
• Tấn công khi đang nhảy và ấn DOWN • Đặt bom khi ngồi lâu • …………………
Thêm chức năng
• Tấn công khi đang nhảy và ấn DOWN • Đặt bom khi ngồi lâu • …………………
• -‐> quá nhiều checker, flag, countdown
Finite State machine
• a
Finite state machine
• Enum + if enum State { STATE_STANDING, STATE_JUMPING, STATE_DUCKING, STATE_DIVING };
void Heroine::handleInput(Input input) { switch (state_) { case STATE_STANDING: if (input == PRESS_B) { state_ = STATE_JUMPING; yVelocity_ = JUMP_VELOCITY; setGraphics(IMAGE_JUMP); } else if (input == PRESS_DOWN) { state_ = STATE_DUCKING; setGraphics(IMAGE_DUCK); } break; …………………………………
Finite state machine
• Enum + if enum State { STATE_STANDING, STATE_JUMPING, STATE_DUCKING, STATE_DIVING };
void Heroine::handleInput(Input input) { switch (state_) { case STATE_STANDING: if (input == PRESS_B) { state_ = STATE_JUMPING; yVelocity_ = JUMP_VELOCITY; setGraphics(IMAGE_JUMP); } else if (input == PRESS_DOWN) { state_ = STATE_DUCKING; setGraphics(IMAGE_DUCK); } break; …………………………………
Ø Số lượng state tăng Ø Mỗi state có dữ liệu riêng
l Countdown l Timing
State pa)ern
• Mỗi state được implement riêng • State < -‐-‐ > Behavior • StateInterface
class HeroineState { public: virtual void handleInput(Heroine& heroine, Input input) {} virtual void update(Heroine& heroine) {} virtual void enter(Heroine& heroine){} };
class DuckingState : public HeroineState{ public: DuckingState() : chargeTime_(0) {} void handleInput(Heroine& heroine, Input input) { if (input == RELEASE_DOWN) { // Change to standing state... heroine.setGraphics(IMAGE_STAND); } } void update(Heroine& heroine) { chargeTime_++; if (chargeTime_ > MAX_CHARGE){ heroine.superBomb(); } } private: int chargeTime_; };
class Heroine { public: void handleInput(Input input) { state_-‐>handleInput(*this, input); } void update() { state_-‐>update(*this); } void sw^chState(HeroineState* new_state) { state_ = new_state; state_-‐>enter (*this); } // Other methods... private: HeroineState* state_; };
Các state khác
• Standing, Jumping, DivingState
Hoàn cảnh sử dụng
• Hành vi phụ thuộc vào một vài trạng thái của object
• Phân chia được hoạt động của object ra những state khác biệt, cụ thể
• Object phản hồi theo những chuỗi input hoặc sự kiện
Nhận xét
• Thêm state dễ dàng – Sơ đồ chuyển trạng thái – Tách rời các state
• Quản lý giữa các state rõ ràng – Bỏ flag, checker….
THẢO LUẬN
Thực hành
• Nhân vật có 3 trạng thái – Đứng – Chạy chậm – Chạy nhanh
• KeyboardDelegate • StatePa)ern