策略模式與簡單java例項
策略模式的定義:[color=red]定義了演算法簇,分別封裝起來,讓它們之間可以相互替換,此模式讓演算法的變化獨立於使用演算法的客戶。[/color]
首先看策略模式的定義,[color=red]演算法簇[/color]也就是一群實現了同一個介面的實現類,[color=red]讓它們之間可以相互替換[/color]的意思也就是要針對介面程式設計,而不是針對類程式設計。[color=red]此模式讓演算法的變化獨立於使用演算法的客戶[/color]是說,採用何種演算法只取決於呼叫者。
現在說說例子:
一個格鬥遊戲,角色類Fighter可以使用很多武器,不同武器攻擊力以及特殊效果不同,比如使用劍能有一定機率造成額外傷害,斧子有一定機率造成雙倍傷害。如果不使用模式的情況下實現這個遊戲的話,Fighter就應該有一些方法:attackWithSword(),attackWithAxe()。如果劍類武器又有:鐵劍、霜之哀傷,又要為這兩把劍寫兩個方法。如果有1000個武器呢?(當然實現這個的方法還有很多,尤其是笨方法很多。。。)
為了避免以上情況,我們定義一個介面:
讓所有武器去實現這個介面,所有實現了這個介面的類,都叫演算法簇。
現在,抽象類劍,實現了這個介面,這裡劍是一個種類,而不是一個具體武器,所以是抽象類:
劍這個類裡定義了傷害值,特殊攻擊的傷害值,特殊攻擊的觸發機率,並且在這裡定義了特殊攻擊的演算法。這樣做有什麼好處呢?看了子類就知道了:
大家看到了,子類很簡單,只要定義一下名字,傷害,以及特殊攻擊傷害、特殊攻擊機率而已,因為具體演算法實現已經由父類實現了。
同樣的,還有斧類武器:
武器就寫這麼多吧,現在看看Fighter,它就是策略模式定義中的[color=red]使用演算法的客戶[/color]
可以看到,Fighter攻擊的時候只是去呼叫了自身武器的attackWithWeapon(Fighter fighter)方法。這就證實了策略模式的定義,[color=red]定義了演算法簇,分別封裝起來,讓他們之間可以相互替換[/color],這些武器就是演算法簇,使用者只要更換掉自己想要使用的實現類就行了,在呼叫演算法的時候,依然只是呼叫演算法實現的介面。
看下測試類
測試結果:
首先看策略模式的定義,[color=red]演算法簇[/color]也就是一群實現了同一個介面的實現類,[color=red]讓它們之間可以相互替換[/color]的意思也就是要針對介面程式設計,而不是針對類程式設計。[color=red]此模式讓演算法的變化獨立於使用演算法的客戶[/color]是說,採用何種演算法只取決於呼叫者。
現在說說例子:
一個格鬥遊戲,角色類Fighter可以使用很多武器,不同武器攻擊力以及特殊效果不同,比如使用劍能有一定機率造成額外傷害,斧子有一定機率造成雙倍傷害。如果不使用模式的情況下實現這個遊戲的話,Fighter就應該有一些方法:attackWithSword(),attackWithAxe()。如果劍類武器又有:鐵劍、霜之哀傷,又要為這兩把劍寫兩個方法。如果有1000個武器呢?(當然實現這個的方法還有很多,尤其是笨方法很多。。。)
為了避免以上情況,我們定義一個介面:
package com.Weapon;
import com.fighter.Fighter;
public interface WeaponBehavior {
public void attackWithWeapon(Fighter fighter);
public String getName();
public void setName(String name);
}
讓所有武器去實現這個介面,所有實現了這個介面的類,都叫演算法簇。
現在,抽象類劍,實現了這個介面,這裡劍是一個種類,而不是一個具體武器,所以是抽象類:
package com.Weapon;
import java.util.Random;
import com.fighter.Fighter;
//劍類武器有一定機率造成額外的傷害
public abstract class Sword implements WeaponBehavior {
// 普通傷害
int damage;
String name;
// 特殊攻擊的傷害
int specialDamage;
// 特殊攻擊的觸發機率
int probability;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getDamage() {
return damage;
}
public void setDamage(int damage) {
this.damage = damage;
}
@Override
public void attackWithWeapon(Fighter fighter) {
normalAttack(fighter);
specialAttack(fighter);
}
protected void normalAttack(Fighter fighter) {
System.out.println("用" + this.getName() + "對" + fighter.getName()
+ "造成了" + this.getDamage() + "基本傷害。");
fighter.loseLife(this.getDamage());
}
protected void specialAttack(Fighter fighter) {
Random r = new Random();
int i = r.nextInt(100);
if (i < this.probability) {
System.out.println(this.getName() + "觸發了特殊效果,對" + fighter.getName()
+ "造成了" + this.specialDamage + "點額外傷害。");
fighter.loseLife(this.specialDamage);
}
}
}
劍這個類裡定義了傷害值,特殊攻擊的傷害值,特殊攻擊的觸發機率,並且在這裡定義了特殊攻擊的演算法。這樣做有什麼好處呢?看了子類就知道了:
package com.Weapon;
import com.fighter.Fighter;
/*
* 霜之哀傷,攻擊力100,有百分之50造成額外的50點傷害。
* */
public class Frostmourne extends Sword {
public Frostmourne()
{
this.setName("霜之哀傷");
this.setDamage(100);
specialDamage=50;
probability=50;
}
@Override
protected void specialAttack(Fighter fighter) {
super.specialAttack(fighter);
}
}
大家看到了,子類很簡單,只要定義一下名字,傷害,以及特殊攻擊傷害、特殊攻擊機率而已,因為具體演算法實現已經由父類實現了。
同樣的,還有斧類武器:
package com.Weapon;
import java.util.Random;
import com.fighter.Fighter;
//斧類武器有一定機率造成雙倍傷害
public abstract class Axe implements WeaponBehavior {
// 普通傷害
int damage;
String name;
// 特殊攻擊的傷害
int specialDamage;
// 特殊攻擊的觸發機率
int probability;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getDamage() {
return damage;
}
public void setDamage(int damage) {
this.damage = damage;
}
@Override
public void attackWithWeapon(Fighter fighter) {
normalAttack(fighter);
specialAttack(fighter);
}
protected void normalAttack(Fighter fighter) {
System.out.println("用" + this.getName() + "對" + fighter.getName()
+ "造成了" + this.getDamage() + "基本傷害。");
fighter.loseLife(this.getDamage());
}
protected void specialAttack(Fighter fighter) {
Random r = new Random();
//斧子有一定機率造成雙倍傷害
this.specialDamage=damage*2;
int i = r.nextInt(100);
if (i < this.probability) {
System.out.println(this.getName() + "觸發了特殊效果,對" + fighter.getName()
+ "造成了" + this.specialDamage + "點額外傷害。");
fighter.loseLife(this.specialDamage);
}
}
}
package com.Weapon;
import com.fighter.Fighter;
/*
* 公正使者,攻擊力100,有百分之30機率造成雙倍傷害。
* */
public class Axe1 extends Axe {
public Axe1()
{
this.setName("公正使者");
this.setDamage(100);
probability=30;
}
@Override
protected void specialAttack(Fighter fighter) {
super.specialAttack(fighter);
}
}
武器就寫這麼多吧,現在看看Fighter,它就是策略模式定義中的[color=red]使用演算法的客戶[/color]
package com.fighter;
import com.Weapon.WeaponBehavior;
public class Fighter {
private int life;
private String name;
private WeaponBehavior weapon;
public Fighter(String name,WeaponBehavior weapon)
{
this.weapon=weapon;
this.name=name;
this.life=1000;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void hit(Fighter fighter)
{
this.weapon.attackWithWeapon(fighter);
}
public int getLife() {
return life;
}
private void setLife(int life) {
this.life = life;
}
public WeaponBehavior getWeapon() {
return weapon;
}
public void setWeapon(WeaponBehavior weapon) {
this.weapon = weapon;
}
public void loseLife(int damage)
{
this.setLife(this.getLife()-damage);
}
public void changeWeapon(WeaponBehavior weapon)
{
System.out.println(this.getName()+"裝備了"+weapon.getName());
this.setWeapon(weapon);
}
}
可以看到,Fighter攻擊的時候只是去呼叫了自身武器的attackWithWeapon(Fighter fighter)方法。這就證實了策略模式的定義,[color=red]定義了演算法簇,分別封裝起來,讓他們之間可以相互替換[/color],這些武器就是演算法簇,使用者只要更換掉自己想要使用的實現類就行了,在呼叫演算法的時候,依然只是呼叫演算法實現的介面。
看下測試類
package com.main;
import com.Weapon.Axe1;
import com.Weapon.Frostmourne;
import com.fighter.Fighter;
public class Main {
public static void main(String[] args) {
Fighter player=new Fighter("player",new Frostmourne());
Fighter computer=new Fighter("computer",new Frostmourne());
player.hit(computer);
System.out.println(computer.getName()+"還剩下"+computer.getLife()+"生命");
player.hit(computer);
System.out.println(computer.getName()+"還剩下"+computer.getLife()+"生命");
//這裡更換了演算法(武器)
player.changeWeapon(new Axe1());
player.hit(computer);
System.out.println(computer.getName()+"還剩下"+computer.getLife()+"生命");
player.hit(computer);
System.out.println(computer.getName()+"還剩下"+computer.getLife()+"生命");
player.hit(computer);
System.out.println(computer.getName()+"還剩下"+computer.getLife()+"生命");
player.hit(computer);
System.out.println(computer.getName()+"還剩下"+computer.getLife()+"生命");
}
}
測試結果:
用霜之哀傷對computer造成了100基本傷害。
霜之哀傷觸發了特殊效果,對computer造成了50點額外傷害。
computer還剩下850生命
用霜之哀傷對computer造成了100基本傷害。
霜之哀傷觸發了特殊效果,對computer造成了50點額外傷害。
computer還剩下700生命
player裝備了公正使者
用公正使者對computer造成了100基本傷害。
computer還剩下600生命
用公正使者對computer造成了100基本傷害。
公正使者觸發了特殊效果,對computer造成了200點額外傷害。
computer還剩下300生命
用公正使者對computer造成了100基本傷害。
computer還剩下200生命
用公正使者對computer造成了100基本傷害。
computer還剩下100生命
相關文章
- 策略模式例項模式
- Java中的策略模式,完成一個簡單地購物車,兩種付款策略例項教程Java模式
- 策略模式+單例模式+簡單工廠模式:推送服務模式單例
- JavaScript單例模式概念與例項JavaScript單例模式
- java多執行緒結合單例模式例項,簡單實用易理解Java執行緒單例模式
- 《JAVA與設計模式》之單例模式Java設計模式單例
- Java的Socket通訊簡單例項Java單例
- Java 關於策略模式+簡單工廠模式下的思考Java模式
- 策略模式簡單運用模式
- C++學習隨筆——簡單的單例設計模式例項C++單例設計模式
- 單例模式,真不簡單單例模式
- websocket簡單例項Web單例
- java 單例模式Java單例模式
- Java單例模式Java單例模式
- 單例模式 - 只有一個例項單例模式
- 單例模式的 Java 實現與思考單例模式Java
- 單例與單例項之爭單例
- 單例模式就是如此簡單單例模式
- 設計模式系列——3.簡單工廠模式與策略模式總結設計模式
- Java設計模式–單例模式Java設計模式單例
- Java設計模式——單例模式Java設計模式單例
- Java設計模式--單例模式Java設計模式單例
- Java設計模式 | 單例模式Java設計模式單例
- Java設計模式【單例模式】Java設計模式單例
- Java設計模式-單例模式Java設計模式單例
- Jndi使用好處,與簡單例項【Tomcat】單例Tomcat
- Java單例模式與反射及序列化Java單例模式反射
- Java - 反射機制與單例設計模式Java反射單例設計模式
- 極簡設計模式-單例模式設計模式單例
- 策略模式原來這麼簡單!模式
- java狀態模式例項解析Java模式
- opengl簡單入門例項
- javascript事件冒泡簡單例項JavaScript事件單例
- Spark 簡單例項(基本操作)Spark單例
- javascript this用法和簡單例項JavaScript單例
- 簡單的單例模式其實也不簡單單例模式
- javascript設計模式單例模式簡單介紹JavaScript設計模式單例
- java單例設計模式Java單例設計模式