• 设计模式 | 组合模式(composite)


    定义:

    将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

    结构:(书中图,侵删)

    一个Component接口:定义统一的方法
    若干树枝(Composite)类(继承Component):可包含若干个叶子(Leaf)节点
    若干树叶(Leaf)类:叶子节点
     
    书中说到这个模式有两种方式:
    透明方式:在Component接口中定义添加和移除子节点的方法,但是叶子节点不需要这两个方法。这样写可以保持客户端调用的一致性。
    安全方式:不在Component接口中定义添加和移除子节点的方法,直接在叶子节点中定义,这样写省去了叶子节点中的无用代码,但是客户端需要添加判断。

    实例:

    书中举到一个例子说是,假如你在word修改字体的大小时,你修改一个字和一段文字操作都是相同的。用户不用对此有差别操作,程序也不用差别对待。
    然后,就让我想到了游戏中的队伍系统,在某些游戏里是可以跟随的,队长操纵自己,整个队伍都会跟着一起行动,和队长一个人行动没有什么区别。
     
    玩家操纵的目标接口(Component):
    package designpattern.composite;
    
    public abstract class Target {
        private String name;// 名称
    
        public abstract void add(Target target);// 增加节点
    
        public abstract void remove(Target target);// 删除节点
    
        public abstract void move();// 移动
    
        public abstract void attack();// 攻击
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
    }
    玩家类(Leaf):
    package designpattern.composite;
    
    public class Player extends Target {
        private String name;
    
        public Player(String name) {
            super();
            this.name = name;
        }
    
        @Override
        public void move() {
            System.out.println("[" + name + "]正在移动");
        }
    
        @Override
        public void attack() {
            System.out.println("[" + name + "]发动攻击");
        }
    
        @Override
        public void add(Target target) {
        }
    
        @Override
        public void remove(Target target) {
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "Player [name=" + name + "]";
        }
    
    }
    队伍类(Composite):
    package designpattern.composite;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Team extends Target {
        List<Target> team = new ArrayList<>();
    
        @Override
        public void add(Target target) {
            team.add(target);
            System.out.println(target.getName() + "加入队伍");
        }
    
        @Override
        public void remove(Target target) {
            team.remove(target);
            System.out.println(target.getName() + "离开队伍");
        }
    
        @Override
        public void move() {
            System.out.println(teamMembers() + "组成的队伍正在移动");
        }
    
        @Override
        public void attack() {
            System.out.println(teamMembers() + "组成的队伍发动攻击");
        }
    
        private String teamMembers() {
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append("[");
            for (Target target : team) {
                stringBuffer.append(target.getName() + " ");
            }
            stringBuffer.append("]");
            return stringBuffer.toString();
        }
    }
    客户端:
    package designpattern.composite;
    
    public class Client {
        public static void main(String[] args) {
            Player captainAmerica = new Player("美国队长");
            captainAmerica.move();
            captainAmerica.attack();
    
            System.out.println("----------复联成立----------");
            Player ironMan = new Player("钢铁侠");
            Player hulk = new Player("绿巨人");
            Team team = new Team();
            team.add(captainAmerica);
            team.add(ironMan);
            team.add(hulk);
    
            team.move();
            team.attack();
    
            System.out.println("----------发生矛盾--------");
            team.remove(ironMan);
    
            team.move();
            team.attack();
        }
    }
    结果输出:
    [美国队长]正在移动
    [美国队长]发动攻击
    ----------复联成立----------
    美国队长加入队伍
    钢铁侠加入队伍
    绿巨人加入队伍
    [美国队长 钢铁侠 绿巨人 ]组成的队伍正在移动
    [美国队长 钢铁侠 绿巨人 ]组成的队伍发动攻击
    ----------发生矛盾--------
    钢铁侠离开队伍
    [美国队长 绿巨人 ]组成的队伍正在移动
    [美国队长 绿巨人 ]组成的队伍发动攻击

    总结:

    这个模式用在两个事物存在一定的包含关系,但是他们的行为又是一致的,为了让客户可以方便统一的使用他们。
    套用书中的话:组合模式让客户可以一致的使用组合结构和单个对象。
  • 相关阅读:
    Oozie时bin/oozied.sh start或bin/oozied.sh run出现Bootstrap进程无法启动,http://bigdatamaster:11000/oozie界面也无法打开?
    [ACM] POJ 2253 Frogger (最短路径变形,每条通路中的最长边的最小值)
    Echoprint系列--Android编译与调用
    shell编程之文本与日志过滤
    C++中搜索、截取字符串
    Swift中的UIKit重力学
    hbase0.96 put流程 源码分析
    [Docker]初次接触
    工作日志2014-08-25
    Flex和Servlet结合上传文件报错(二)
  • 原文地址:https://www.cnblogs.com/imoqian/p/10974504.html
Copyright © 2020-2023  润新知