大话编程-组合模式

组合模式(Composite Pattern)

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

动机

定义了包含基本对象和组合对象的类层次结构,基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断递归下去,任何用到基本对象的地方都可以使用组合对象。

###适用场景

  • 你想表示对象部分-整体层次结构。

  • 你希望用户忽略组合对象与单个对象不同,用户将统一地使用组合结构中的所以对象。

结构

image.png

代码示例:多功能的菜单

//菜单组合
public abstract class MenuComponent {
    public void add(MenuComponent menuComponent){
        throw new UnsupportedOperationException();
    }
    public void remove(MenuComponent menuComponent){
        throw new UnsupportedOperationException();
    }
    public MenuComponent getChild(int i) {
        throw new UnsupportedOperationException();
    }
    public String getName() {
        throw new UnsupportedOperationException();
    }
    public String getDescription() {
        throw new UnsupportedOperationException();
    }
    public double getPrice() {
        throw new UnsupportedOperationException();
    }
    public boolean isVegetarian() {
        throw new UnsupportedOperationException();
    }
    public void print() {
        throw new UnsupportedOperationException();
    }
}
//根节点菜单
public class Menu extends MenuComponent{
    ArrayList menuComponents = new ArrayList();
    String name;
    String description;

    public Menu(String name, String description) {
        this.name = name;
        this.description = description;
    }

    @Override
    public void add(MenuComponent menuComponent) {
        menuComponents.add(menuComponent);
    }

    @Override
    public void remove(MenuComponent menuComponent) {
        menuComponents.remove(menuComponent);
    }

    @Override
    public MenuComponent getChild(int i) {
        return (MenuComponent) menuComponents.get(i);
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getDescription() {
        return description;
    }
    //打印店铺菜单,
    @Override
    public void print() {
        System.out.println("\n" + getName());
        System.out.println(", " + getDescription());
        System.out.println("--------------------");

        Iterator iterator = menuComponents.iterator();
        while (iterator.hasNext()) {
            MenuComponent menuComponent = (MenuComponent) iterator.next();
            //具体店铺打印详细菜单
            menuComponent.print();
        }
    }
}
//子节点菜单,根节点菜单的具体菜单
public class MenuItem extends MenuComponent{
    String name;
    String description;
    boolean vegetarian;
    double price;

    public MenuItem (String name, String description, boolean vegetarian, double price) {
        this.name = name;
        this.description = description;
        this.vegetarian = vegetarian;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public String getDescription() {
        return description;
    }

    public double getPrice() {
        return price;
    }

    public boolean isVegetarian() {
        return vegetarian;
    }
    //打印详细菜单
    public void print() {
        System.out.println("  " + getName());
        if (isVegetarian()) {
            System.out.println("(v)");
        }
        System.out.println(", " + getPrice());
        System.out.println("    --" + getDescription());
    }
}
//服务员
public class Waitress {
    private MenuComponent allMenus;

    public Waitress(MenuComponent allMenus) {
        this.allMenus = allMenus;
    }
    
    //只展示菜单
    public void printMenu() {
        allMenus.print();
    }
}
public class Client{
     public static void main(String[] args) {
        //店铺菜单
        MenuComponent dinerMenu = new Menu("饭店", "这是饭店菜单");
        MenuComponent cafeMenu = new Menu("咖啡店", "这是咖啡店菜单");
        //总菜单
        MenuComponent allMenu = new Menu("总菜单", "this is all menu");
        //给总菜单添加店铺菜单
        allMenu.add(dinerMenu);
        allMenu.add(cafeMenu);

        //店铺添加详细菜单
        dinerMenu.add(new MenuItem("辣椒炒肉", "其实就是辣椒炒辣椒,没得肉", false, 15));
        dinerMenu.add(new MenuItem("蛋炒饭", "没有鸡蛋只有饭", true, 10));

        cafeMenu.add(new MenuItem("卡布奇诺", "给阿姨倒一杯卡布奇诺", false, 50));
        cafeMenu.add(new MenuItem("摩卡", "摩卡咖啡", false, 50));

        //服务员只负责展示菜单
        Waitress waitress = new Waitress(allMenu);
        waitress.printMenu();
    }
}

总结

组合模式可以实现组件共享,组件共享是很有用的,比如它可以减少对存储的需求,但是当一个组件只有一个父部件时,很难共享组件。组合对象的关键在于它定义了一个抽象构建类,它既可表示叶子对象,也可表示容器对象,客户仅仅需要针对这个抽象构建进行编程,无须知道他是叶子对象还是容器对象,都是一致对待。

大话编程那些事儿 wechat
欢迎关注微信公众号

访问更多文章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值