经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
设计模式 | 组合模式(composite)
来源:cnblogs  作者:莫愆  时间:2019/6/4 18:15:14  对本文有异议

定义:

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

结构:(书中图,侵删)

 

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

实例:

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

总结:

这个模式用在两个事物存在一定的包含关系,但是他们的行为又是一致的,为了让客户可以方便统一的使用他们。
套用书中的话:组合模式让客户可以一致的使用组合结构和单个对象。

原文链接:http://www.cnblogs.com/imoqian/p/10974504.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号