1.把常變動的部分封裝起來
2.使用實作介面來建立物件
3.多用合成少用繼承
範例
public class Simulator { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Character sprite = new Sprite();//使用多型建立 Character normalman = new NormalMan();//同上 Character samuri = new Samuri();//同上 Character monsterboss = new MonsterBoss();//同上 //executeAttack 是 Character 類別的方法,方法內容為 ab 呼叫 attack 方法 //而各 ab 是在每個建構子中建立不同的 ab sprite.executeAttack(); normalman.executeAttack(); samuri.executeAttack(); monsterboss.executeAttack(); //動態改變 ab monsterboss.setAttackBehavior(new AttackBySword()); monsterboss.executeAttack(); monsterboss.setAttackBehavior(new AttackByMagic()); monsterboss.executeAttack(); } }
Character.java
public abstract class Character { AttackBehavior ab;//(攻擊行為)常變動的部分封裝成類別,宣告為介面型態可以動態改變 public void executeAttack(){ ab.attack(); } public void setAttackBehavior(AttackBehavior ab){ this.ab = ab; } } class NormalMan extends Character{ public NormalMan(){ ab = new AttackByHand(); } } class Sprite extends Character{ public Sprite(){ ab = new AttackByMagic(); } } class Samuri extends Character{ public Samuri(){ ab = new AttackBySword(); } } class MonsterBoss extends Character{ public MonsterBoss(){ ab = new AttackByHand(); } }
如果之後還有新的角色(Character)種類,可以繼續擴充,不影響原角色類別
public interface AttackBehavior { public void attack(); } class AttackByHand implements AttackBehavior{ public void attack(){ System.out.println("AttackByHand"); } } class AttackBySword implements AttackBehavior{ public void attack(){ System.out.println("AttackBySword"); } } class AttackByMagic implements AttackBehavior{ public void attack(){ System.out.println("AttackByMagic"); } }
如果之後有新的攻擊行為種類,可以繼續擴充,不影響原攻擊行為類別