1.类关联结构
先上两个类
/**
* 员工类
* @author Administrator
*
*/
class Staff {
private String name;
private int age;
private Badge badge;
public void show(){
System.out.println("姓名:"+this.name+",年龄:"+this.age);
}
public Badge getBadge(){
return this.badge;
}
public void setBadge(Badge badge){
this.badge = badge;
}
public Staff(String name,int age){
this.name = name;
this.age = age;
}
}
/**
* 工牌类
* @author Administrator
*
*/
class Badge{
private int id;
private String name;
private Staff staff;
public void show(){
System.out.println("工号:"+this.id+",姓名:"+this.name);
}
public Staff getStaff(){
return this.staff;
}
public void setStaff(Staff staff){
this.staff = staff;
}
public Badge(int id,String name){
this.id = id;
this.name = name;
}
}
一个员工类一个工牌类
每一个员工都有自己的工牌,在公司不小心把工牌弄掉,那么捡到工牌的一看就知道这工牌是谁的了,这就是关联。当然反过来也一样,根据员工找的自己的工牌。
public class Test {
public static void main( String[] args ){
Staff staff = new Staff("张三",19 );
Badge badge = new Badge(1001, "张三");
staff.setBadge(badge);
badge.setStaff(staff);
badge.getStaff().show(); //根据工牌找到员工
staff.getBadge().show(); //根据员工找到工牌
}
}
输出结果:
姓名:张三,年龄:19
工号:1001,姓名:张三
这就是关联,在员工类中定义工牌类,在工牌类中定义员工类,这样就可以相互调用各自的方法了。
2.自身关联
比如你是一个主管佩戴一个工牌,你手底下有两个员工也要佩戴工牌,那你不可能又去创建一个主管类来关联工牌类吧。所以这里我们就要用的自身关联。
/**
* 员工类
* @author Administrator
*
*/
class Staff {
private String name;
private int age;
private Badge badge;
private Staff[] staffs; //自身关联 对象数组
public void show(){
System.out.println("姓名:"+this.name+",年龄:"+this.age);
}
public Staff(String name,int age){
this.name = name;
this.age = age;
}
public Staff[] getStaffs() {
return staffs;
}
public void setStaffs(Staff[] staffs) {
this.staffs = staffs;
}
public Badge getBadge(){
return this.badge;
}
public void setBadge(Badge badge){
this.badge = badge;
}
}
/**
* 工牌类
* @author Administrator
*
*/
class Badge{
private int id;
private String name;
private Staff staff;
public void show(){
System.out.println("工号:"+this.id+",姓名:"+this.name);
}
public Staff getStaff(){
return this.staff;
}
public void setStaff(Staff staff){
this.staff = staff;
}
public Badge(int id,String name){
this.id = id;
this.name = name;
}
}
在员工类下面定义一个员工类数组,这样就相当于一个主管下面有很多员工。
public class Test {
public static void main( String[] args ){
Staff staff = new Staff("张三",19 );
Badge badge = new Badge(1001, "张三");
badge.setStaff(staff);
staff.setBadge(badge);
//继续添加员工
Staff dome1 = new Staff("李四", 12);
Staff dome2 = new Staff("王五", 11);
dome1.setBadge(new Badge(1002, "李四"));
dome2.setBadge(new Badge(1003, "王五"));
staff.setStaffs(new Staff[]{dome1,dome2});
badge.setStaff(staff);
staff.show();
for (int i = 0; i < staff.getStaffs().length; i++) {
staff.getStaffs()[i].show();
staff.getStaffs()[i].getBadge().show();
}
}
}
输出:
姓名:张三,年龄:19
姓名:李四,年龄:12
工号:1002,姓名:李四
姓名:王五,年龄:11
工号:1003,姓名:王五
3.合成设计模式
合成模型模式(Composite)属于队形的结构模式,有时又叫做部分-整体模式(Part-Whole)。
合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。
树
合成模式的结果就像树枝和树叶一样分别是两个节点,树枝可以分出树叶,而树叶不能分出树枝。
树节点的种类有很多,这个图是从上到下的还有双向、从下到上的
合成模式的构件角色:
- 抽象构件角色:ComPoslit
- 树叶构件角色:Lred
- 树枝构件角色:ComPoslits
合成模式有两种实现:
- 安全性
特点:在树枝类型中声明所有管理子类对象的方法,这样的方法就是不透明,因为树叶类型的对象没有管理子类对象的方法,只能由树枝类型来操作,但是很有安全性。
代码:
/**
* 抽象构件
* @author Administrator
*
*/
public abstract class ComPoslit {
public abstract void dore();
}
import java.util.Vector;
/**
* 树枝构件
* @author Administrator
*
*/
public class Composlits extends ComPoslit {
private Vector list= new Vector();
@Override
public void dore() {
// TODO Auto-generated method stub
for (int i = 0; i < list.size(); i++) {
ComPoslit comPoslit = (ComPoslit)list.get(i);
comPoslit.dore();
}
}
/**
* 添加一个字对象
* @param comPoslit
*/
public void add(ComPoslit comPoslit){
list.add(comPoslit);
}
/**
* 删除一个子对象
* @param comPoslit
*/
public void remove(ComPoslit comPoslit){
list.remove(comPoslit);
}
/**
* 返还一个子对象
* @param i
* @return
*/
public ComPoslit getChild(int i){
return (ComPoslit)list.get(i);
}
}
/**
* 树叶构件
* @author Administrator
*
*/
public class Lred extends ComPoslit {
@Override
public void dore() {
// TODO Auto-generated method stub
}
}
- 透明性
特点:在抽象类型中声明所有管理子类对象的方法,让树叶和树枝都可以管理,这样做的好处是所有的构件类都有相同的接口。缺点就是不够安全,因为树叶类对象和合成模式还是有区别的。
代码:
/**
* 抽象构件
* @author Administrator
*
*/
public abstract class ComPoslit {
public abstract void dore();
/**
* 添加一个字对象
* @param comPoslit
*/
public abstract void add(ComPoslit comPoslit);
/**
* 删除一个子对象
* @param comPoslit
*/
public abstract void remove(ComPoslit comPoslit);
/**
* 返还一个子对象
* @param i
* @return
*/
public abstract ComPoslit getChild(int i);
}
/**
* 树枝构件
* @author Administrator
*
*/
public class Composlits extends ComPoslit {
private Vector list= new Vector();
@Override
public void dore() {
// TODO Auto-generated method stub
for (int i = 0; i < list.size(); i++) {
ComPoslit comPoslit = (ComPoslit)list.get(i);
comPoslit.dore();
}
}
/**
* 添加一个字对象
* @param comPoslit
*/
public void add(ComPoslit comPoslit){
list.add(comPoslit);
}
/**
* 删除一个子对象
* @param comPoslit
*/
public void remove(ComPoslit comPoslit){
list.remove(comPoslit);
}
/**
* 返还一个子对象
* @param i
* @return
*/
public ComPoslit getChild(int i){
return (ComPoslit)list.get(i);
}
}
/**
* 树叶构件
* @author Administrator
*
*/
public class Lred extends ComPoslit {
@Override
public void dore() {
// TODO Auto-generated method stub
}
@Override
public void add(ComPoslit comPoslit) {
// TODO Auto-generated method stub
}
@Override
public void remove(ComPoslit comPoslit) {
// TODO Auto-generated method stub
}
@Override
public ComPoslit getChild(int i) {
// TODO Auto-generated method stub
return null;
}
}
优点:
- 合成模式可以很容易的增加新种类的构件
- 使用合成模式可以是客户端变得很容易设计,因为客户端不需要知道构件是树叶构件还是树枝构件。
缺点:
- 使用合成模式后,控制树枝构件的类型就不太容易
- 用继承的方法来增加新的行为很困难。