`

Java设计模式之组合模式(Composite)

 
阅读更多
Composite模式定义:
        将对象以树形结构组织起来,以达成“部分-整体” 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性.

Composite模式理解:
        想到Composite就应该想到树形结构图。组合体内这些对象都有共同接口,当组合体一个对象的方法被调用执行时,Composite将遍历(Iterator)整个树形结构,寻找同样包含这个方法的对象并实现调用执行。可以用牵一动百来形容。

Composite模式好处:
        1.使客户端调用简单,客户端可以一致的使用组合结构或其中单个对象,用户就不必关系自己处理的是单个对象还是整个组合结构,这就简化了客户端代码。
        2.更容易在组合体内加入对象部件. 客户端不必因为加入了新的对象部件而更改代码

如何使用:
        Step 1:
        首先定义一个接口或抽象类(设计模式通用方式),其他设计模式对接口内部定义限制不多,Composite却有个规定,那就是要在接口内部定义一个用于访问和管理Composite组合体对象的方法.

        Step 2:
        以抽象类或接口的方式定义一个供继承或实现的类或接口:
       
import java.util.Iterator;

public abstract class Equipment {

	private String name;

	public Equipment(String name) {
		this.name = name;
	}

	// 实体价格
	public abstract double netPrice();

	// 折扣价格
	public abstract double discountPrice();

	// 增加部件的方法
	public boolean add(Equipment equipment) {
		return false;
	}

	// 移除部件方法
	public boolean remove(Equipment equipment) {
		return false;
	}

	// 组合体内访问各个部件的方法.
	public Iterator iter() {
		return null;
	}

}
        

        这个抽象类定义的就是一个组合体内所有对象都具有的共同方法和属性。

        Step 3:
        下面接着定义组合体内原件对象的实体类:
       
public class Disk extends Equipment {

	// 硬盘实体价格
	public static double diskNetPrice = 2.0;

	// 硬盘折扣价格
	public static double diskDiscountPrice = 1.0;

	public Disk(String name) {
		super(name);
	}

	@Override
	public double netPrice() {
		return diskNetPrice;
	}

	@Override
	public double discountPrice() {
		return diskDiscountPrice;
	}

}


        Disk是组合体内的一个对象,或称一个部件,这个部件是个单独元素( Primitive)。还有一种可能是,一个部件也是一个组合体,就是说这个部件下面还有'儿子',这是树形结构中通常的情况,应该比较容易理解。

        Step 4:
        现在我们在继续定义一个组合体:
       
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

public abstract class CompositeEquipment extends Equipment {

	private int i = 0;

	// 定义一个List,用来保存组合体内的各个子对象.
	private List<Equipment> equipment = new ArrayList<Equipment>();

	public CompositeEquipment(String name) {
		super(name);
	}

	public boolean add(Equipment equipment) {
		if (equipment instanceof Disk && this instanceof Chassis) {
			System.out.println("在盘盒里面放了一个硬盘");
		} else if (equipment instanceof Chassis && this instanceof Cabinet) {
			System.out.println("在柜子里面放了一个盘盒");
		}
		this.equipment.add(equipment);
		return true;
	}

	public double netPrice() {
		double netPrice = 0.;
		if (this instanceof Cabinet) {
			System.out.println("我是在柜子的组合对象里面.柜子本身价格为:"
					+ Cabinet.cabinetNetPrice);
		} else if (this instanceof Chassis) {
			System.out.println("我是在盘盒的组合对象里面.盘盒本身价格为:"
					+ Chassis.chassisNetPrice);
		}
		Iterator<Equipment> iter = equipment.iterator();
		while (iter.hasNext()) {
			Equipment equipment = (Equipment) iter.next();
			if (equipment instanceof Chassis) {
				System.out.println("在柜子里面发现一个盘盒,计算它的价格");
			} else if (equipment instanceof Disk) {
				System.out.println("在盘盒里面发现一个硬盘,计算它的价格");
				System.out.println("硬盘本身价格为:" + Disk.diskNetPrice);
			}
			netPrice += equipment.netPrice();
		}
		return netPrice;
	}

	public double discountPrice() {
		double discountPrice = 0.;
		Iterator<Equipment> iter = equipment.iterator();
		while (iter.hasNext()) {
			discountPrice += ((Equipment) iter.next()).discountPrice();
		}
		return discountPrice;
	}

	// 这里提供用于访问自己组合体内的部件方法。
	// 上面Disk之所以没有,是因为Disk是个单独(Primitive)的元素.
	public Iterator iter() {
		return equipment.iterator();
	}

	// 重载Iterator方法
	public boolean hasNext() {
		return i < equipment.size();
	}

	// 重载Iterator方法
	public Object next() {
		if (hasNext())
			return equipment.get(i++);
		else
			throw new NoSuchElementException();
	}

}

        上面CompositeEquipment继承了Equipment,同时为自己里面的对象们提供了外部访问的方法,重载了Iterator,Iterator是Java的Collection的一个接口,是Iterator模式的实现.

        Step 5:
        我们在继续创建CompositeEquipment的两个具体类:盘盒Chassis和箱子Cabinet,箱子里面可以放很多东西,如底板,电源盒,硬盘盒等;盘盒里面可以放一些小设备,如硬盘 软驱等。无疑这两个都是属于组合体性质的。

public class Cabinet extends CompositeEquipment {

	public static double cabinetNetPrice = 10.0;
	public static double cabinetDiscountPrice = 5.0;

	public Cabinet(String name) {
		super(name);
	}

	// 柜子本身价格以及放在柜子里面盒子的价格.
	public double netPrice() {
		return cabinetNetPrice + super.netPrice();
	}

	public double discountPrice() {
		return cabinetDiscountPrice + super.discountPrice();
	}
}


public class Chassis extends CompositeEquipment {

	public static double chassisNetPrice = 2.0;
	public static double chassisDiscountPrice = 1.0;

	public Chassis(String name) {
		super(name);
	}

	// 盒子的价格以及盒子里面硬盘价格.
	public double netPrice() {
		return chassisNetPrice + super.netPrice();
	}

	//
	public double discountPrice() {
		return chassisDiscountPrice + super.discountPrice();
	}
}


        至此我们完成了整个Composite模式的架构。

        Step 6:
        现在我们来看一下组合模式的使用场景:
       
public class Client {

	public static void main(String[] args) {

		Cabinet cabinet = new Cabinet("柜子");

		Chassis chassis = new Chassis("盘盒");

		// 将盘盒装到箱子里
		cabinet.add(chassis);

		// 将硬盘装到盘盒里
		chassis.add(new Disk("硬盘"));

		// 查询整个柜子的实体价格
		System.out.println("整个柜子的实体价格(包括里面的盘盒和硬盘) =" + cabinet.netPrice());

		// 查询整个柜子的折扣价格
		System.out.println("整个柜子的折扣价格(包括里面的盘盒和硬盘) =" + cabinet.discountPrice());
	}
}

        上面调用的方法netPrice()或discountPrice(),实际上Composite使用Iterator遍历了整个树形结构,寻找同样包含这个方法的对象并实现调用执行.

        Composite是个很巧妙体现智慧的模式,在实际应用中,如果碰到树形结构,我们就可以尝试是否可以使用这个模式。
分享到:
评论

相关推荐

    JAVA设计模式chm文档

    设计模式之Composite(组合) 设计模式之Decorator(油漆工) 设计模式之Bridge 设计模式之Flyweight(享元) 行为模式: 设计模式之Template 设计模式之Memento(备忘机制) 设计模式之Observer 设计模式之Chain of ...

    《java设计模式》课后习题模拟试题解答——刘伟.zip

    Java设计模式是软件工程中的一种最佳实践,它总结了在特定场景下解决常见问题的经验,为程序员提供了可重用的解决方案。本资料“《java设计模式》课后习题模拟试题解答——刘伟.zip”主要涵盖了Java设计模式的学习与...

    《Java设计模式》课后答案-刘伟.rar

    《Java设计模式》是刘伟教授的一本关于设计模式的教材,主要面向高等学校的学生和对Java编程有深入兴趣的开发者。设计模式是软件工程中的一种重要思想,它封装了在特定场景下的问题解决方案,可以提高代码的可读性、...

    23种java设计模式.pdf

    " JAVA 设计模式概述" JAVA 设计模式是指在软件设计过程中,为了提高代码的可维护性、灵活性和可扩展性所使用的一些惯用解决方案。JAVA 设计模式可以分为三种:创建模式、结构模式和行为模式。 1. 创建模式 创建...

    Java设计模式刘伟书本中模拟考试答案

    在《Java设计模式》这本书的模拟试题及其参考答案中,涉及了多条设计模式的知识点,以及它们的应用场景和实现方法。现在将这些知识点详细地解释如下: 1. 开闭原则(Open-Closed Principle, OCP): 开闭原则是面向...

    JAVA设计模式-chm版

    包括适配器模式(Adapter)、桥接模式(Bridge)、装饰器模式(Decorator)、外观模式(Facade)、组合模式(Composite)、享元模式(Flyweight)和代理模式(Proxy)。这些模式可以帮助我们更好地组织代码,实现...

    java常用设计模式-组合模式

    java常用设计模式-组合模式 组合模式(Composite Pattern)是一种结构型设计模式,它允许你将对象组合成树形结构以表示“部分-整体”的层次结构。这种模式使得客户端可以统一对待单个对象和对象组合。在组合模式中...

    JAVA设计模式之结构模式

    这是JAVA设计模式中属于结构模式的部分,包括Flyweight(共享模式)、Bridge(桥模式)、Decorator(装饰模式)、Composite(组合模式)、Adapter(适配器模式)、Proxy(代理模式)、Facade (外观模式)的源代码。其中有些模式中...

    JAVA设计模式(chm版)

    2. 结构型模式:关注对象组合和类的继承,例如适配器模式(Adapter)、装饰器模式(Decorator)、桥接模式(Bridge)、组合模式(Composite)、外观模式(Facade)、享元模式(Flyweight)和代理模式(Proxy)。...

    Java设计模式之禅

    《Java设计模式之禅》是一本深入浅出讲解设计模式的书籍,书中不仅包含23种经典设计模式的案例,还详细介绍了设计模式背后的思想和原则,适合初学者以及对设计模式有一定了解的程序员阅读。本书旨在帮助读者理解如何...

    23种JAVA设计模式和15种J2EE设计模式

    ### 23种JAVA设计模式和15种J2EE设计模式详解 #### 一、JAVA设计模式概览 在软件工程领域,设计模式是一种在特定情境下解决常见问题的有效方法。Java作为一种广泛使用的编程语言,拥有丰富的设计模式库来帮助...

    java设计模式PPT

    包括适配器模式(Adapter)、桥接模式(Bridge)、装饰模式(Decorator)、外观模式(Facade)、享元模式(Flyweight)、组合模式(Composite)和代理模式(Proxy)。如装饰模式可以在不修改原有对象的基础上添加新...

    Java设计模式之组合模式

    ### Java设计模式之组合模式详解 #### 定义与动机 组合模式,也称为部分-整体模式,是一种结构型设计模式,它允许我们构建复杂的层级结构,并以一致的方式处理单个对象和组合对象。组合模式的主要动机是创建一个树...

    JAVA设计模式

    **JAVA设计模式** 在软件工程领域,设计模式是一种在特定情境下解决问题的可复用解决方案。它们是经验的总结,代表了在特定上下文中被广泛接受的、经过时间考验的最佳实践。Java设计模式是面向对象编程中的一种重要...

    JAVA设计模式.影印版.zip

    Java设计模式是软件工程中的一种最佳实践,它提供了一套标准的解决方案,用于解决在编写可维护、可扩展和高效代码时经常遇到的问题。这些模式是经验丰富的开发人员在面对相似问题时经过反复验证和提炼得出的结果。在...

    Java设计模式导读.pdf

    Java设计模式是软件工程领域中一套被广泛认知和使用的标准解决方案,用于解决在软件设计中遇到的特定问题。设计模式可以提高软件开发的效率、可读性和可维护性。在面向对象的编程语言Java中,设计模式通过利用Java...

    Java设计模式及案例1

    组合模式(Composite)可以将对象组合成树形结构,表示部分-整体层次结构,使得客户端可以一致地处理单个对象和对象集合。 行为型模式则关注对象间的交互和行为的定义。观察者模式使得一个对象的状态改变能够自动...

    java设计模式(疯狂java联盟版)

    Java设计模式是软件工程中的一种重要思想,它总结了在解决特定问题时,程序员们反复使用的最佳实践。这些模式提供了一种在特定情况下组织代码的标准方法,使得代码更易理解和复用。《Java设计模式(疯狂Java联盟版)...

    java设计模式中英文各种版本打包下载 学习设计模式必备材料

    2. 结构型模式(Structural Patterns):如适配器模式(Adapter)、桥接模式(Bridge)、装饰器模式(Decorator)、组合模式(Composite)、外观模式(Facade)、享元模式(Flyweight)和代理模式(Proxy)。...

Global site tag (gtag.js) - Google Analytics