对委托机制的初步体会(软构)

马上要开始写实验三了,其中要用到委托机制。老师上课讲的太快了,没怎么记住,今天复习整理一下委托机制。
委托其实就是一个对象请求另一个对象的功能,与它相对的是继承,implements。继承的好处是子类可以直接使用父类的所有方法,但问题是如果我们的子类不需要父类的一些方法需要override为空方法或用其他方式来禁用。而委托在这方面就很安全,用户无法直接得到我们委托给的那个对象。
其实我在实验2中就已经使用了委托机制,比如GraphPoet类中定义了一个Graph类的变量来使用它的一些方法,FriendShipGraph中也是一样。
下面通过讨论两种实现排序的方式来加强理解。注意使用SortedMap和SortedSet时也需要类似的方法。
第一种:实现Comparator接口
Comparator接口里声明的compare函数默认是两个int参数,如果我们不需要修改它的参数类型,即我们的比较器比较的也是两个int时,我们可以通过如下方式方便的定义我们的比较器:

final Comparator ASCENDING = (i,j) -> i<j;

然后这个比较器就可以被传给sort之类的函数了:

Collections.sort(list,ASCENDING);

但如果比价器比较的两个对象是我们自己定义的类,我们就可以写一个Comparator的实现然后override compare()函数:

public class Edge{
	Vertex s,t;
	double weight;
	...
}
public class EdgeComparator implements Comparator<Edge>{
	@Override int compare(Edge o1,Edge o2){
		if(o1.getWeight()>o2.getWeight())
			return 1;
		else if(..==..)return 0;
		else return -1;
	}
}
public void sort(List<Edge> edges){
	Comparator comparator=new EdgeComparator();
	Collections.sort(edges,comparator);
}

这种方法就是用了委托的机制,即比较两个Edge类的对象时委托一个EdgeComparator对象来做。
第二种方法:使用继承的机制。让Edge实现Comparable接口,然后override(这里讲义上写的是override,但讲义代码里并没写override标签,我感觉父类里定义的参数应该不是Edge类,所以这里应该是重载而不是重写) compareTo()方法。这样不需要构建新的Comparator类,比较代码放在ADT内部。

public class Edge implements Comparable<Edge>{
	Vertex s,t;
	double weight;
	...
	public int compareTo(Edge o){
		if(this.getWeight()>o.getWeight())
			return 1;
		else if(..==..) return 0;
		else return -1;
	}
}
public void sort(List<Edge> edges){
	Collections.sort(edges);
}

委托的类型:
下面设A类委托B类进行说明
1.Dependency:临时性的委托
A类的fields里没有B类,只是A类的某些方法的参数或内部使用了B类。
2.Association:永久性的委托
A类的fields里有B类。它有两种具体形态Composition和Aggregation。Composition是A类的构造函数不需要传入B类的参数,即A类对它委托的B类有默认设置,直接写在构造函数里了;Aggregation是A类的构造函数要传入一个B类的参数,代表A类委托这个特定的B类去做事。
实验三用到的CRP原则(Composite reuse principle):委托优先于继承
实验三的局部共性有三个维度,构建继承树的实现模式如下:
1.首先是需要定义三个维度,每个维度两种可能共6个接口。
2.针对某一维度的两个接口实现具体类
3.第二个维度分别拓展第一个维度的两个具体类,第二个维度实现4个具体类。
4.第三个维度拓展第二个维度的4个具体类,实现8个具体类。
我们会发现上述方案的复用性并不够好,当然它好于只为维度定义接口然后在各个子类中实现具体操作(这样每个维度的两种实现代码都要在剩下两个维度的4种组合中实现一次),但是只是继承树第一层的方法代码只需写一次,第二层的就要写2次了,第3层就要写4次,仍然是指数级的,设维度为m,我们要写的代码总数只是由
2 m − 1 ∗ ( m ∗ 2 ) 2^{m-1}*(m*2) 2m1(m2)
变成了
2 + 4 + . . . + 2 m = 2 m + 1 − 2 2+4+...+2^{m}=2^{m+1}-2 2+4+...+2m=2m+12
仍然是指数级的。
而使用委托机制步骤如下:
1.同上面的1,定义6个接口
2.每个接口写一个实现类,共6个实现类
3.对每个具体任务写一个接口,它是上面6个接口的一种组合。
4.对每个具体任务的接口写实现类,实现类里面委托2里的实现类。
注意局部共性代码的实现是放在2中的,4中只是进行了委托,所以按上面的算法我们写的代码总数是 2 m 2m 2m的,非常优秀。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值