感覺好像用不到的感覺,開始學了設計模式後才發現物件導向 "程式碼再利用" 的精神.
今天來介紹一個會用到 interface、abstract class 的設計模式,策略模式~
先不考慮程式,單純看名字(設計模式的名字很重要),策略 strategy:
什麼是策略? 對我來說策略是 針對同一個問題的不同解決方法
例如 填飽肚子 是你的問題,那 吃飯、吃麵、吃麵包 就個別是你的策略,都是能讓你填飽肚子的食物,就看你選擇哪一個。
[程式示範]
假設現在有一款遊戲,裡面有四個角色,騎士、法師、妖精、王子
(很熟悉?!代表我們同年代 )
以前我在寫都會把 "攻擊行為" 寫在個角色內.
騎士會揮劍
法師會放魔法
妖精會射弓劍
王子會...叫人
轉成Java
// 騎士
public class Knight {
// 攻擊
public void Attack(){
System.out.println("揮劍");
}
}
// 妖精
public class Elf {
// 攻擊
public void Attack(){
System.out.println("射弓劍");
}
}
// 王子
public class Prince {
// 攻擊
public void Attack(){
System.out.println("叫人...");
}
}
// 魔法師
public class Wizard {
// 攻擊
public void Attack(){
System.out.println("放魔法");
}
}
現在你想新增一個角色黑暗妖精,是不是又再多寫一個黑妖的類別,然後再寫他的攻擊方法...如果想增加其他技能,要個別增加,如果角色有100個...這太累人了這時就是abstract class出場的時候,你可以增加一個角色的抽象類別
// 抽象類別 角色
public abstract class charater {
// 一般攻擊
public abstract void attack();
// 技能
public abstract void ability();
// 顯示角色
public abstract void display();
}
再將各個職業角色繼承charater類別,基本上你所有的角色就有這三個方法了.
騎士範例
// 騎士
public class Knight extends Charater {
// 一般攻擊
@Override
public void attack() {
System.out.println("揮劍");
}
// 魔法攻擊
@Override
public void ability() {
System.out.println("放魔法");
}
// 顯示角色
@Override
public void display() {
System.out.println("我是騎士");
}
}
現在想新增一個村子裡NPC的角色,NPC不會攻擊也不會放魔法,該怎麼辦呢?
直接空白不寫?那如果有個會攻擊的NPC怎麼辦?
這時可以利用interface,降臨!!!~
宣告兩個interface
- AttackHavior
- MagicAbility
public interface AttackBehavior {
void attack();
}
public interface MagicAbility {
void magic();
}
實作這兩個攻擊方式的類別
//揮劍攻擊
public class WieldAttack implements AttackBehavior {
@Override
public void attack() {
System.out.println("揮劍");
}
}
// 一級魔法
public class LevelOneMagic implements MagicAbility {
@Override
public void magic() {
System.out.println("使用一級魔法");
}
}
// 不會物理攻擊
public class AttackNoWay implements AttackBehavior {
@Override
public void attack() {
System.out.println("不會攻擊");
}
}
// 不會魔法攻擊
public class MagicNoWay implements MagicAbility {
@Override
public void magic() {
System.out.println("不會放魔法");
}
}
再將charater改成
// 抽象類別 角色
public abstract class Charater {
// 物理攻擊行為
AttackBehavior attackBehavior;
// 魔法攻擊行為
MagicAbility magicAbility;
// 一般攻擊
public void attack(){
attackBehavior.attack();
}
// 技能
public void ability(){
magicAbility.magic();
}
// 顯示角色
public abstract void display();
}
此時的騎士類別變成
// 騎士
public class Knight extends Charater {
// 建構子預設攻擊行為
public Knight() {
this.attackBehavior = new WieldAttack();
this.magicAbility = new LevelOneMagic();
}
// 顯示角色
@Override
public void display() {
System.out.println("我是騎士");
}
}
NPC類別
//NPC
public class NPC extends Charater {
// 建構子預設攻擊行為
public NPC() {
this.attackBehavior = new AttackNoWay();
this.magicAbility = new MagicNoWay();
}
// 顯示角色
@Override
public void display() {
System.out.println("我是NPC");
}
}
在主方法執行
Charater knight = new Knight(); knight.display(); knight.attack(); knight.ability(); Charater npc = new NPC(); npc.display(); npc.attack(); npc.ability();便能看到
我是騎士 揮劍 使用一級魔法 我是NPC 不會攻擊 不會放魔法
那如果想動態設定物理攻擊和魔法攻擊呢?
只要在Charater類別上修改成
// 抽象類別 角色
public abstract class Charater {
AttackBehavior attackBehavior;
MagicAbility magicAbility;
// 一般攻擊
public void attack(){
attackBehavior.attack();
}
// 技能
public void ability(){
magicAbility.magic();
}
// 顯示角色
public abstract void display();
// 設定物理攻擊
public void setAttackBehavior(AttackBehavior attackBehavior){
this.attackBehavior = attackBehavior;
}
// 設定魔法攻擊
public void setMagicAbility(MagicAbility magicAbility){
this.magicAbility = magicAbility;
}
}
如此一來 你要增加其他新的攻擊跟魔法就更輕鬆了,物件導向真的很強大!!!
快去試試你的策略模式吧~~
沒有留言:
張貼留言