王者荣耀有非常多的英雄,而且每一个不同的英雄也有其自己对应的皮肤。玩家可以根据需要购买不同的英雄皮肤,体验不同英雄皮肤在对局中的感受。
在本实例中,根据组合模式的特点,列举了英雄李白及其皮肤的树形价格表。
组合模式理解:
高度概括:将对象组合成树形结构一表示“部分-整体”的层次结构。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节点时,用户的重要代码不需要做出修改
缺点:
使得设计更加复杂。客户端需要花更多时间理清类之间的层次关系。(这个是几乎所有设计模式所面临的问题)。
组合模式的适用情景:
①当想表示对象的部分整体层次结构
②希望用户用一致的方式处理个体对象和组合对象
主函数【应用(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);
}
}
更多设计模式在王者荣耀中的应用请点击我的→设计模式在王者荣耀中的应用专栏。
感谢阅读