从王者荣耀看设计模式(五.组合模式)

从王者荣耀看设计模式(组合模式)

1597476-20190903094415618-1319200905.jpg

一.简介

在王者荣耀这款游戏中,我们可以在商店中购买英雄。英雄由法师、射手、打野等职业组合而成,其中各个职业由中国元素的英雄和外国元素的英雄组成,玩家可根据需要挑选并购买英雄

二.组合模式

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。

  • 这其中的设计原则有:
  1. 组合模式允许你将对象组合成树形结构来表现”部分-整体“的层次结构,使得客户以一致的方式处理单个对象以及对象的组合。
  2. 组合模式实现的最关键的地方是——简单对象和复合对象必须实现相同的接口。这就是组合模式能够将组合对象和简单对象进行一致处理的原因。
  3. 组合模式必须包含的内容:

    组合部件(Component):它是一个抽象角色,为要组合的对象提供统一的接口。
    叶子(Leaf):在组合中表示子节点对象,叶子节点不能有子节点。
    合成部件(Composite):定义有枝节点的行为,用来存储部件,实现在Component接口中的有关操作,如增加(Add)和删除(Remove)。

  • 组合模式模式的优点
    1. 组合模式使得客户端代码可以一致地处理对象和对象容器,无需关系处理的单个对象,还是组合的对象容器。
    2. 将”客户代码与复杂的对象容器结构“解耦。
    3. 可以更容易地往组合对象中加入新的构件。
  • 组合模式模式的缺点
    1. 使得设计更加复杂。客户端需要花更多时间理清类之间的层次关系。(这个是几乎所有设计模式所面临的问题)。
  • 组合模式适用场景
    1. 当想表达对象的部分-整体的层次结构时。
    2. 希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象时。
三.结构图

结构图

四.设计类图

类图

五.代码实现

Type类(组合部件):为要组合的对象提供统一的接口

package com.game.heroShop;
/*
 * 组合部件(抽象角色)为要组合的对象提供统一的接口
 */

public abstract class Type {
    //设置组合部件的名称
    private String rootName;
    //创建有参的构造方法
    public Type(String rootName) {
        super();
        this.rootName = rootName;
    }
    //创建无参的构造方法
    public Type() {
    }
    //get.set
    public String getName() {
        return rootName;
    }
 
    public void setName(String rootName) {
        this.rootName = rootName;
    }
    
    //为要组合的对象提供接口add
    public abstract void add(Type heroType);
    //为要组合的对象提供接口remove
    public abstract void romove(Type heroType);
    //为要组合的对象提供接口display
    public abstract void display(int depth);
}

ProfessionType类(合成部件类):实现接口中有关操作

package com.game.heroShop;

import java.util.ArrayList;
import java.util.List;
/*
 * 合成部件类
 * 定义有枝节点的行为,用来存储部件,实现在Component接口中的有关操作,如增加(Add)和删除(Remove)
 */
public class ProfessionType extends Type {
    //定义集合类存放Type类型
    private List<Type> cList;
    
    //创建无参的够着函数,初始化集合
    public ProfessionType() {
        cList = new ArrayList<Type>();
    }
    //创建有参的够着函数,初始化集合
    public ProfessionType(String name) {
        super(name); 
        cList = new ArrayList<Type>() ; 
    }
 
    //实现组合部件接口中的add操作
    public void add(Type heroType) {
        cList.add(heroType);
    }
    
    //实现组合部件接口中的remove操作
    public void romove(Type heroType) {
        cList.remove(heroType);
    }
 
    //实现组合部件接口中的display操作
    public void display(int depth) {
        // TODO Auto-generated method stub
        StringBuilder sb = new StringBuilder("");
        for (int i = 0; i < depth; i++) {
            sb.append("-"); 
        }
        System.out.println(new String(sb) + this.getName());
        for (Type c : cList) {
            c.display(depth + 2);
        }
    }
}

ClassificationA类(叶子类),表示子节点对象

package com.game.heroShop;
/*
 *叶子类,在组合中表示子节点对象,叶子节点不能有子节点。
 */

public class ClassificationA extends Type {
    //创建有参的构造方法
    public ClassificationA(String heroName) {
        super(heroName);
    }
    
    //实现组合部件接口中的相关操作
    public void add(Type heroName) {}
    
    public void romove(Type heroName) {}
    
    public void display(int depth) {
        StringBuilder sb = new StringBuilder("");
        for (int i = 0; i < depth; i++) {
            sb.append("-");
        }
        System.out.println(new String(sb) + this.getName());
    }
}

ClassificationB类(叶子类),表示子节点对象

package com.game.heroShop;
/*
 *叶子类,在组合中表示子节点对象,叶子节点不能有子节点。
 */
public class ClassificationB extends Type {
    //创建有参的构造方法
    public ClassificationB(String heroName) {
        super(heroName);
    }
    
    //实现组合部件接口中的相关操作
    public void add(Type heroName) {}
    
    public void romove(Type heroName) {}
    
    public void display(int depth) {
        StringBuilder sb = new StringBuilder("");
        for (int i = 0; i < depth; i++) {
            sb.append("-");
        }
        System.out.println(new String(sb) + this.getName());
    }
}

HeroShopTest类(测试类)

package com.game.heroShopTest;
/*
 * 测试类
 */

import com.game.heroShop.ClassificationB;
import com.game.heroShop.ProfessionType;
import com.game.heroShop.ClassificationA;
import com.game.heroShop.Type;

public class HeroShopTest {
    public static void main(String[] args) {
        //创建合成部件实例
        Type root=new ProfessionType();
        root.setName("所有英雄");
        //法师,射手,打野组合成所有英雄
        Type master = new ProfessionType("法师");
        Type shooter = new ProfessionType("射手");
        Type killBeast = new ProfessionType("打野");
        root.add(master);
        root.add(shooter);
        root.add(killBeast);
        //中国法师和外国法师组合成法师职业
        Type master1=new ProfessionType("中国法师");
        Type master2=new ProfessionType("外国法师");
        master.add(master1);
        master.add(master2);
        //中国法师由钟馗等英雄组合而成
        master1.add(new ClassificationB("钟馗"));
        //外国法师由米莱迪等英雄组合而成
        master2.add(new ClassificationB("米莱迪"));
        
        //中国射手和外国射手组合成射手职业
        Type shooter1=new ProfessionType("中国射手");
        Type shooter2=new ProfessionType("外国射手");
        shooter.add(shooter1);
        shooter.add(shooter2);
        //中国射手由鲁班七号和虞姬等英雄组合而成
        shooter1.add(new ClassificationA("鲁班七号"));
        shooter1.add(new ClassificationA("虞姬"));
        //外国射手由马可波罗等英雄组合而成
        shooter2.add(new ClassificationA("马可波罗"));
        
        //中国打野和外国打野组合成打野职业
        Type killBeast1=new ProfessionType("中国打野");
        Type killBeast2=new ProfessionType("外国打野");
        killBeast.add(killBeast1);
        killBeast.add(killBeast2);
        //中国打野由李白,韩信等英雄组合而成
        killBeast1.add(new ClassificationA("韩信"));
        killBeast1.add(new ClassificationA("李白"));
        //外国打野由宫本武藏等英雄组合而成
        killBeast2.add(new ClassificationA("宫本武藏"));
        root.display(0);
    }
}

运行结果
结果

转载于:https://www.cnblogs.com/miaowulj/p/11451185.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值