组合模式(Bridge Pattern) – 设计模式之结构型模式

组合模式(Bridge Pattern) – 设计模式之结构型模式:

目录

组合模式(Component Pattern)

类图

例子1:

过程:

类图:

代码:

抽象组件:PlayerComposite

球员:BasketPlayer

球队: PlayerComposite

联盟: BasketLeager

测试

球员测试:

结果:

球队测试:

结果:

总结:                                 


组合模式(Component Pattern)

定义: Compose objects into tree structures to represent part-whole hierarchies. Composit clients treat individual objects and compositions of objects uniformly.

 

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

 

当需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象不同,统一地使用组合结构中的所有对象时,就应该考虑用组合模式。

 

 

类图

组合模式通用的类图

 

 组合模式(Bridge Pattern) – 设计模式之结构型模式

 

抽象构件 Component 它是组合模式的精髓, 定义参加组合对象的共有方法和属性,可以定义一些默认的行为或属性

 

常见的组合内容:

    字符  单词  句子 段落  文章

    水滴  水流  小溪  江河  大海

    员工  部门  公司

 

例子1:

过程:

 组合模式(Bridge Pattern) – 设计模式之结构型模式

 

 

类图:

组合模式(Bridge Pattern) – 设计模式之结构型模式

 

代码:

抽象组件:PlayerComposite

public abstract class PlayerComposite {

  public abstract void add(PlayerComposite player);

  public abstract  void remove(PlayerComposite player);

  public abstract void display();
}

 

球员:BasketPlayer

public class BasketPlayer extends PlayerComposite {

  private String name;
  private String role;
  private int age;

  public BasketPlayer(String name, String role,int age) {
    this.name = name;
    this.role = role;
    this.age = age;
  }

  @Override
  public String toString() {
    return "{" +
            "name='" + name + '\'' +
            ", role='" + role + '\'' +
            ", age=" + age +
            '}';
  }

  @Override
  public void add(PlayerComposite player) {
    //
  }

  @Override
  public void remove(PlayerComposite player) {
    //
  }

  @Override
  public void display() {
    //
  }
}

 

球队: PlayerComposite

public class BasketTeams extends PlayerComposite {

  private String name;
  private String position;

  private List<PlayerComposite> basketPlayers;

  public BasketTeams(String name, String position,List<PlayerComposite> basketPlayers) {
    this.name = name;
    this.position = position;
    this.basketPlayers = basketPlayers;
  }

  public BasketTeams(BasketPlayer... basketPlayers) {
    for (BasketPlayer basketPlayer : basketPlayers) {
      this.add(basketPlayer);
    }
  }

  @Override
  public void add(PlayerComposite player) {
    this.basketPlayers.add(player);
  }

  @Override
  public void remove(PlayerComposite player) {
    this.basketPlayers.remove(player);
  }

  @Override
  public void display() {
    System.out.println("球队: "+name+" 位于:"+position +" 队伍里面有:");
    basketPlayers.forEach(e -> System.out.println(e.toString()));
  }

}

 

联盟: BasketLeager

public class BasketLeager extends PlayerComposite {

  private String name;

  private List<PlayerComposite> basketTeams;

  public BasketLeager(String name, List<PlayerComposite> basketTeams) {
    this.name = name;
    this.basketTeams = basketTeams;
  }

  @Override
  public void add(PlayerComposite player) {
    this.basketTeams.add(player);
  }

  @Override
  public void remove(PlayerComposite player) {
    this.basketTeams.remove(player);
  }

  @Override
  public void display() {
    System.out.println("篮球联盟: "+name+" 球队有 ");
    basketTeams.forEach(PlayerComposite::display);
  }

}

 

测试

球员测试:

public class PlayerTest {

  public static void main(String[] args) {
    PlayerComposite  brown = new BasketPlayer("Brown","Small Forward",23);
    PlayerComposite  tatum =  new BasketPlayer("Tatum","Power Forward",22);
    PlayerComposite  walk = new BasketPlayer("Walk","Point Guard",29);
    PlayerComposite  mike = new BasketPlayer("Mike","Point Guard",35);
    List<PlayerComposite> basketPlayers = Lists.newArrayList(
            brown,tatum,walk,mike
    );

    PlayerComposite cellticTeam = new BasketTeams("凯尔特人", "东部",basketPlayers);
    cellticTeam.display();
    // 转会来的球员
    PlayerComposite aoJielie = new BasketPlayer("AoJielie", "Center", 22);
    cellticTeam.add(aoJielie);
    // 转会走的球员
    cellticTeam.remove(mike);
    System.out.println("====== change ===========");
    cellticTeam.display();

  }
}

 

结果:

球队: 凯尔特人 位于:东部 队伍里面有:

{name='Brown', role='Small Forward', age=23}

{name='Tatum', role='Power Forward', age=22}

{name='Walk', role='Point Guard', age=29}

{name='Mike', role='Point Guard', age=35}

====== 交易后球队情况 ===========

球队: 凯尔特人 位于:东部 队伍里面有:

{name='Brown', role='Small Forward', age=23}

{name='Tatum', role='Power Forward', age=22}

{name='Walk', role='Point Guard', age=29}

{name='AoJielie', role='Center', age=22}

 

球队测试:

public class TeamTest {

  public static void main(String[] args) {

    PlayerComposite  celtics = initTeamCel();
    PlayerComposite  laker =  initTeamLaker();
    List<PlayerComposite> basketTeams = Lists.newArrayList(
            celtics, laker
    );

    PlayerComposite basketLeager = new BasketLeager("NBA 联盟", basketTeams);
    basketLeager.display();
    //  新增加的球队
    PlayerComposite warrior = initTeamWarri();
    basketLeager.add(warrior);
    // 从联盟退出的球队
    basketLeager.remove(celtics);
    System.out.println("====== change ===========");
    basketLeager.display();
  }

  public static PlayerComposite initTeamCel(){
    PlayerComposite  brown = new BasketPlayer("Brown","Small Forward",23);
    PlayerComposite  tatum =  new BasketPlayer("Tatum","Power Forward",22);
    PlayerComposite  walk = new BasketPlayer("Walk","Point Guard",29);
    PlayerComposite  mike = new BasketPlayer("Mike","Point Guard",35);
    List<PlayerComposite> basketPlayers = Lists.newArrayList(
            brown,tatum,walk,mike
    );
    return new BasketTeams("凯尔特人", "东部",basketPlayers);
  }

  public static PlayerComposite initTeamLaker(){
    PlayerComposite  james =  new BasketPlayer("詹姆斯","小前锋",37);
    PlayerComposite  shat = new BasketPlayer("浓眉","大前锋",28);
    PlayerComposite  pork = new BasketPlayer("加索尔","中锋",32);
    List<PlayerComposite> basketPlayers = Lists.newArrayList(
            james,shat,pork
    );
    return new BasketTeams("湖人队", "西部",basketPlayers);
  }

  public static PlayerComposite initTeamWarri(){
    PlayerComposite  cury =  new BasketPlayer("库里","控球后卫",31);
    PlayerComposite  green = new BasketPlayer("格林","大前锋",28);
    PlayerComposite  tom = new BasketPlayer("汤普森","得分后卫",32);
    List<PlayerComposite> basketPlayers = Lists.newArrayList(
            cury,green,tom
    );
    return new BasketTeams("勇士队", "西部",basketPlayers);
  }
}

 

结果:

篮球联盟: NBA 联盟 球队有

球队: 凯尔特人 位于:东部 队伍里面有:

{name='Brown', role='Small Forward', age=23}

{name='Tatum', role='Power Forward', age=22}

{name='Walk', role='Point Guard', age=29}

{name='Mike', role='Point Guard', age=35}

球队: 湖人队 位于:西部 队伍里面有:

{name='詹姆斯', role='小前锋', age=37}

{name='浓眉', role='大前锋', age=28}

{name='加索尔', role='中锋', age=32}

====== change ===========

篮球联盟: NBA 联盟 球队有

球队: 湖人队 位于:西部 队伍里面有:

{name='詹姆斯', role='小前锋', age=37}

{name='浓眉', role='大前锋', age=28}

{name='加索尔', role='中锋', age=32}

球队: 勇士队 位于:西部 队伍里面有:

{name='库里', role='控球后卫', age=31}

{name='格林', role='大前锋', age=28}

{name='汤普森', role='得分后卫', age=32}

 

总结:                                 

优点: 

     1、高层模块调用简单。

     2、节点*增加和删除。

缺点:

      在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。

使用场景:部分--整体场景,如树形菜单,文件、文件夹的管理,员工、部门

 

   除去对节点的操作,组合模式的类图像不像模板模式? 尤其是抽象组件 是模板方法里面的抽象方法(Abstract Method),加具体方法就是一个模板方法了。

 

上一篇:There is no Layer2 option in WireGuard


下一篇:STP生成树实验