·
組合模式在王者榮耀中的應用
·
一、簡述
王者榮耀有非常多的英雄,而且每一個不同的英雄也有其自己對應的皮膚。玩家可以根據需要購買不同的英雄皮膚,體驗不同英雄皮膚在對局中的感受。
在本實例中,根據組合模式的特點,列舉了英雄李白及其皮膚的樹形價格表。
二、組合模式(Composite Pattern)
組合模式理解:
高度概括:將對象組合成樹形結構一表示“部分-整體”的層次結構。Composite使用戶對單個對象和組合對象的使用具有一致性。
如果一個對象包含另一個對象的引用,稱這個對象爲組合對象。如果當前組合對象作爲一個整體的話,那麼它所包含的對象就是該整體的一部分,如果一個對象不含有其它對象的引用,稱這個對象爲個體對象。在編寫程序時,我們希望許多個體對象和組合對象組成樹形結構,一次表示部分整體的層次結構,並藉助該層次結構,使得用戶能用一致的方式處理個體對象和組合對象。在組成的樹形結構中,個體對象和組合對象都是術中的節點,但是組合對象是具有其他子節點的節點,個體對象是不具有其他字節點的,葉節點也就是說在屬性結構中組合對象所含有的對象將作爲該組合對象的子節點被對待。
組合模式結構中的三種角色:
①抽象組件(Component):抽象組件是一個接口(抽象類),該接口(抽象類)定義了個體對象和組合對象,需要實現的關於操作其子節點的方法,比如add()、remove()以及getChild()等方法。抽象組件也可以定義個體對象和組合對象,用於操作其自身的方法,比如isLeaf()方法等。
②Composite節點(Composite Node):實現components接口類的實例,composite節點不僅可以實現component接口,還可以含有其他Conporsite節點或Leaf節點的引用。
③Leaf節點(Leaf Node):實現component接口類的實例,Leaf節點實現component接口,不可以含有其它composite節點或Leaf節點的引用,因此,葉節點在實現component接口有關操作子節點的方法時,比如add()、remove()和getChild()方法,可讓方法拋出一個異常,也可以實現爲空操作
組合模式的UML類圖:
組合模式的優缺點:
優點:
①組合模式中包含個體對象和組合對象,並形成樹形結構,使用戶可以方便的處理個體對象和組合對象;
②組合對象和個體對象實現了相同的藉口,用戶一般無需區分個體對象和組合對象;
③當增加新的Composite節點和Leaf節點時,用戶的重要代碼不需要做出修改
缺點:
使得設計更加複雜。客戶端需要花更多時間理清類之間的層次關係。(這個是幾乎所有設計模式所面臨的問題)。
組合模式的適用情景:
①當想表示對象的部分整體層次結構
②希望用戶用一致的方式處理個體對象和組合對象
三、王者榮耀角度下實現組合模式結構圖及代碼
eclipse結構圖
主函數【應用(Application)】
Applicayion.java
package angle_compositePattern;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;
import java.awt.*;
public class Application extends JFrame implements TreeSelectionListener{
HeroLiBai hero,skinTypeOne,skinTypeTwo , skin[];
DefaultMutableTreeNode trunk,branch1,branch2, leaf[] ;
JTree heroSkin;
final static int MAX=4;
JTextArea text;
public Application() {
hero=new SkinType("李白",0);
trunk=new DefaultMutableTreeNode(hero);
skinTypeOne=new SkinType("伴生皮膚",0);
branch1=new DefaultMutableTreeNode(skinTypeOne);
skinTypeTwo=new SkinType("特效皮膚",0);
branch2=new DefaultMutableTreeNode(skinTypeTwo);
skin=new SkinLiBai[MAX];
leaf=new DefaultMutableTreeNode[MAX];
skin[0]=new SkinLiBai("範海辛",288);
leaf[0]=new DefaultMutableTreeNode(skin[0]);
skin[1]=new SkinLiBai("敏銳之力",488);
leaf[1]=new DefaultMutableTreeNode(skin[1]);
skin[2]=new SkinLiBai("千年之狐",788);
leaf[2]=new DefaultMutableTreeNode(skin[2]);
skin[3]=new SkinLiBai("鳳求凰",1788);
leaf[3]=new DefaultMutableTreeNode(skin[3]);
hero.add(skinTypeOne);
trunk.add(branch1);
hero.add(skinTypeTwo);
trunk.add(branch2);
for(int i=0;i<1;i++){
skinTypeOne.add(skin[i]);
branch1.add(leaf[i]);
}
for(int i=1;i<MAX;i++){
skinTypeTwo.add(skin[i]);
branch2.add(leaf[i]);
}
heroSkin =new JTree(trunk);
heroSkin.addTreeSelectionListener(this);
text=new JTextArea(20,20);
text.setFont(new Font("宋體",Font.BOLD,12));
text.setLineWrap(true);
setLayout(new GridLayout(1,2));
add(new JScrollPane(heroSkin));
add(new JScrollPane(text));
setBounds(70,80,460,320);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setVisible(true);
}
public void valueChanged(TreeSelectionEvent e){
text.setText(null);
DefaultMutableTreeNode node=(DefaultMutableTreeNode)heroSkin.getLastSelectedPathComponent();
HeroLiBai treeComponent=(HeroLiBai)node.getUserObject();
String allName=Computer.getAllChildrenName(treeComponent);
double totalValue=Computer.computerValue(treeComponent);
String mess=null;
if(treeComponent.isLeaf())
mess=allName+"的價格:\n"+totalValue+"點券";
else
mess=allName+"加在一起的價格:\n"+totalValue+"點券";
text.append(mess+"\n");
double unit=1;
double value=Computer.computerValue(treeComponent,unit);
String name=treeComponent.toString();
if(treeComponent.isLeaf())
mess=name+"的價格"+value+"點券";
else
mess="所有"+name+"的價格"+value+"點券";
text.append("\n"+mess);
}
public static void main(String args[]) {
new Application();
}
}
抽象組件
HeroLiBai.java
package angle_compositePattern;
import angle_compositePattern.HeroLiBai;
import java.util.Iterator;
public interface HeroLiBai{
public void add(HeroLiBai node) ;
public void remove(HeroLiBai node) ;
public HeroLiBai getChild(int index);
public Iterator<HeroLiBai> getAllChildren() ;
public boolean isLeaf();
public double getValue();
}
Composite節點
SkinType.java
package angle_compositePattern;
import angle_compositePattern.HeroLiBai;
import java.util.Iterator;
import java.util.LinkedList;
public class SkinType implements HeroLiBai{
LinkedList<HeroLiBai> list;
double value;
String name;
SkinType(String name,double value){
this.name=name;
this.value=value;
list=new LinkedList<HeroLiBai>();
}
public void add(HeroLiBai node) {
list.add(node);
}
public void remove(HeroLiBai node){
list.remove(node);
}
public HeroLiBai getChild(int index) {
return list.get(index);
}
public Iterator<HeroLiBai> getAllChildren() {
return list.iterator();
}
public boolean isLeaf(){
return false;
}
public double getValue(){
return value;
}
public String toString(){
return name;
}
}
SkinLiBai.java
package angle_compositePattern;
import angle_compositePattern.HeroLiBai;
import java.util.Iterator;
import java.util.LinkedList;
public class SkinLiBai implements HeroLiBai{
LinkedList<HeroLiBai> list;
double value;
String name;
SkinLiBai(String name,double value){
this.name=name;
this.value=value;
list=new LinkedList<HeroLiBai>();
}
public void add(HeroLiBai node) {}
public void remove(HeroLiBai node){}
public HeroLiBai getChild(int index) {
return null;
}
public Iterator<HeroLiBai> getAllChildren() {
return null;
}
public boolean isLeaf(){
return true;
}
public double getValue(){
return value;
}
public String toString(){
return name;
}
}
Leaf節點
Computer.java
package angle_compositePattern;
import angle_compositePattern.HeroLiBai;
import java.util.Iterator;
public class Computer{
public static double computerValue(HeroLiBai node){
double valueSum=0;
if(node.isLeaf()==true){
valueSum=valueSum+node.getValue();
}
if(node.isLeaf()==false){
valueSum=valueSum+node.getValue();
Iterator<HeroLiBai> iterator=node.getAllChildren();
while(iterator.hasNext()){
HeroLiBai p= iterator.next();
valueSum=valueSum+computerValue(p);;
}
}
return valueSum;
}
public static double computerValue(HeroLiBai node,double unit){
double skinWorth=0;
if(node.isLeaf()==true){
skinWorth=skinWorth+node.getValue()*unit;
}
if(node.isLeaf()==false){
Iterator<HeroLiBai> iterator=node.getAllChildren();
while(iterator.hasNext()){
HeroLiBai p= iterator.next();
skinWorth=skinWorth+computerValue(p,unit);
}
}
return skinWorth;
}
public static String getAllChildrenName(HeroLiBai node){
StringBuffer mess= new StringBuffer();
if(node.isLeaf()==true){
mess.append(" "+node.toString());
}
if(node.isLeaf()==false){
mess.append(" "+node.toString());
Iterator<HeroLiBai> iterator=node.getAllChildren();
while(iterator.hasNext()){
HeroLiBai p= iterator.next();
mess.append(getAllChildrenName(p));
}
}
return new String(mess);
}
}
運行結果截圖
更多設計模式在王者榮耀中的應用請點擊我的→設計模式在王者榮耀中的應用專欄。
歡迎留言,一起學習交流~
感謝閱讀