Java设计模式 - 组合模式

本文深入探讨了组合模式的设计理念及其在实际项目中的应用。通过对比不同餐馆菜单的实现方式,详细介绍了如何利用组合模式统一处理单个对象与对象组合,以解决菜单扩展性和兼容性问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

 

组合模式:

组合优点:

组合模式应用:

组合实例:

上述代码 GitHub 地址:https://github.com/baicun/designPatterns


组合模式:

处理具有树形结构的设计模式,具体使用一致的方式来处理个别对象以及不同对象组合。

组合优点:

兼容性强,不必关心处理的是单个对象还是整个组合结构

组合模式应用:

java.AWT Component中的组合模式

组合实例:

类图:

示例:俩家不同的餐馆合并,需要打印出不同组合的菜单,面包馆呢是遍历的集合,而小饭馆呢是遍历的数组,所以需要找一个统一的方法,来解决这个问题,之前使用的迭代器模式进行设计,现在想在小饭馆菜单中增加饭后甜点,他和小饭馆菜是菜单包含菜单,我们称之为容器,这个时候,就需要使用组合模式。

代码:

创建一个大的容器类-MenuComponent.java

public abstract class MenuComponent {

	public String getName() {
		return "";
	}

	public String getDescription() {
		return "";
	}

	public float getPrice() {
		return 0;
	}

	public boolean isVegetable() {
		return false;
	}

	public abstract void print();

	public Iterator getIterator() {
		return new NullIterator();
	}
}

面包馆菜单-CakeHouseMenu.java

public class CakeHouseMenu extends MenuComponent {
    private ArrayList<MenuComponent> menuItems;

    public CakeHouseMenu() {
        menuItems = new ArrayList<MenuComponent>();

        addItem("KFC Cake Breakfast", "boiled eggs&toast&cabbage", true, 3.99f);
        addItem("MDL Cake Breakfast", "fried eggs&toast", false, 3.59f);
        addItem("Stawberry Cake", "fresh stawberry", true, 3.29f);
        addItem("Regular Cake Breakfast", "toast&sausage", true, 2.59f);
    }

    private void addItem(String name, String description, boolean vegetable,
                         float price) {
        MenuItem menuItem = new MenuItem(name, description, vegetable, price);
        menuItems.add(menuItem);
    }

    public Iterator getIterator() {
        return new ComposeIterator(menuItems.iterator());
    }

    @Override
    public void print() {
        System.out.println("****This is CakeHouseMenu****");
    }
}

 小饭馆菜单-DinerMenu.java

public class DinerMenu extends MenuComponent {
    private final static int Max_Items = 5;
    private int numberOfItems = 0;
    private MenuComponent[] menuItems;

    public DinerMenu() {
        menuItems = new MenuComponent[Max_Items];
        addItem("vegetable Blt", "bacon&lettuce&tomato&cabbage", true, 3.58f);
        addItem("Blt", "bacon&lettuce&tomato", false, 3.00f);
        addItem("bean soup", "bean&potato salad", true, 3.28f);
        addItem("hotdog", "onions&cheese&bread", false, 3.05f);
        // 新增饭后甜点
        addSubMenu(new SubMenu());

    }

    private void addItem(String name, String description, boolean vegetable,
                         float price) {
        MenuItem menuItem = new MenuItem(name, description, vegetable, price);
        if (numberOfItems >= Max_Items) {
            System.err.println("sorry,menu is full!can not add another item");
        } else {
            menuItems[numberOfItems] = menuItem;
            numberOfItems++;
        }

    }
    private void addSubMenu(MenuComponent mMenuComponent) {
        if (numberOfItems >= Max_Items) {
            System.err.println("sorry,menu is full!can not add another item");
        } else {
            menuItems[numberOfItems] = mMenuComponent;
            numberOfItems++;
        }

    }

    public Iterator getIterator() {
        return new ComposeIterator(new DinerIterator());
    }

    class DinerIterator implements Iterator {
        private int position;

        public DinerIterator() {
            position = 0;
        }

        @Override
        public boolean hasNext() {
            // TODO Auto-generated method stub
            if (position < numberOfItems) {
                return true;
            }
            return false;
        }

        @Override
        public Object next() {
            // TODO Auto-generated method stub
            MenuComponent menuItem = menuItems[position];
            position++;
            return menuItem;
        }

        @Override
        public void remove() {
            // TODO Auto-generated method stub
        }
    }

    @Override
    public void print() {
        System.out.println("****This is DinerMenu****");
    }
}

饭后甜点-SubMenu.java,集成超类,方便遍历子元素。

public class SubMenu extends MenuComponent {
	private ArrayList<MenuComponent> menuItems;

	public SubMenu() {
		menuItems = new ArrayList<MenuComponent>();

		addItem("Apple Cookie", "Apple&candy&Cookie", true, 1.99f);
		addItem("Banana Cookie", "Banana&candy&Cookie", false, 1.59f);
		addItem("Orange Cookie", "Orange&Cookie", true, 1.29f);
	}

	private void addItem(String name, String description, boolean vegetable,
			float price) {
		MenuItem menuItem = new MenuItem(name, description, vegetable, price);
		menuItems.add(menuItem);
	}

	public Iterator getIterator() {
		return new ComposeIterator(menuItems.iterator());
	}

	@Override
	public void print() {
		System.out.println("****This is SubMenu****");
	};
	// 其他功能代码

}

测试类:

public class MainTest {
	public static void main(String[] args) {
		Waitress mWaitress = new Waitress();
		CakeHouseMenu mCakeHouseMenu = new CakeHouseMenu();
		DinerMenu mDinerMenu = new DinerMenu();
		mWaitress.addComponent(mCakeHouseMenu);
		mWaitress.addComponent(mDinerMenu);
		mWaitress.printVegetableMenu();;
	}
}

上述代码 GitHub 地址:https://github.com/baicun/designPatterns

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值