2021-06-30

						软件构造Delegation

引出:子类可以继承父类的字段、属性和方法,使用“继承”可以较大程度地复用代码。在使用继承时,务必要确定代码中定义的“父类”和“子类”确实存在客观的“父子关系”,而不要去做“为了代码复用而使用继承”的事情,这是舍本逐末的做法,也是滥用继承的体现。滥用继承会破坏类之间客观存在的关系,也会模糊代码所体现的语义。

委派和继承都是为了提高代码的复用性,只是方式不同。
委派:一个对象请求另一个对象的功能,捕获一个操作并将其发送到另一个对象。
继承:利用extends来扩展一个基类。

(1)Association:关联关系,永久性的delegation。被delegation的对象保存在rep中,该对象的类型被永久的与此ADT绑定在了一起。示例代码:

interface Flyable {
	public void fly();
}
interface Quackable {
	public void quack();
}
class FlyWithWings implements Flyable{
	@Override
	public void fly() {
		System.out.println("fly with wings");
	}
}
class Quack implements Quackable{
	@Override
	public void quack() {
		System.out.println("quack like duck");
	}
}
interface Ducklike extends Flyable,Quackable{

}
public class Duck implements Ducklike {
	//delegation
	Flyable flyBehavior;
	Quackable quackBehavior;

	//设置delegation对象实例
	public void setFlyBehavior(Flyable flyBehavior) {
		this.flyBehavior = flyBehavior;
	}

	public void setQuackBehavior(Quackable quackBehavior) {
		this.quackBehavior = quackBehavior;
	}

	//通过delegation实现具体行为
	@Override
	public void fly() {
		this.flyBehavior.fly();
	}

	@Override
	public void quack() {
		this.quackBehavior.quack();
	}

}
public class Client {
	public static void main(String[] args) {
		Flyable f = new FlyWithWings();
		Quackable q = new Quack();
		Duck d = new Duck();
		d.setFlyBehavior(f);
		d.setQuackBehavior(q);
		d.fly();
		d.quack();
	}
}

(2)Dependency:依赖关系,临时性的delegation。把被delegation的对象以参数方式传入。只有在需要的时候才建立与被委派类的联系,而当方法结束的时候这种关系也就随之断开了。示例代码:

public interface Study {
	int study(String content);
}
class StudyInClass implements Study{
	@Override
	public int study(String content) {	
		return 1;
	}
}
class StudyByMooc implements Study{
	@Override
	public int study(String content) {
		return 2;
	}	
}
class Student{
	private String name;
	private Map<String,Integer> scores = new HashMap<String, Integer>();
	
	public Map<String, Integer> getScores() {
		return scores;
	}
	//AF:name为学生名字,scores中的key为学科名字,value为学生成绩
	//RI:学生成绩范围为[0,100]
	public Student(String name) {
		this.name = name;
	}
	public int getFinalScore() {
		int total = 0;
		for(String content:scores.keySet()) {
			total += scores.get(content);
		}
		return total;
	}
	//建立临时性的delegation关系
	public int study(String content,Study method) {
		System.out.print(content + ":\t");
		return method.study(content);
	}
	public void getScore(String content,Study method) {
		int score = method.study(content);
		scores.put(content, score);
	}
	public static void main(String[] args) {
		Study inClass = new StudyInClass();
		Study byMooc = new StudyByMooc();
		Student Wu = new Student("wyf");
		
		Wu.study("软件构造", inClass);
		Wu.getScore("软件构造", inClass);
		System.out.println(Wu.getScores().get("软件构造"));
		Wu.study("计算机系统", byMooc);
		Wu.getScore("计算机系统", byMooc);
		System.out.println(Wu.getScores().get("计算机系统"));
		
		System.out.println("总成绩:" + Wu.getFinalScore());
	}

(3)Composition: 更强的association,但难以变化。也就是以下代码Association中的法二。
(4)Aggregation: 更弱的association,可动态变化。也就是以下代码Association中的法一。

//法一:在构造方法中传入参数绑定
Flyable f = new FlyWithWings();
Duck d = new Duck(f);
d.fly();
class Duck {
	Flyable f; //这个必须由构造方法传入参数绑定
	public Duck(Flyable f) { this.f = f; }
    public void fly(){ f.fly(); }
}
//法二:在rep或构造方法中直接写死
Duck d = new Duck();
d.fly();
class Duck {
    //这两种实现方式的效果是相同的
	Flyable f = new FlyWithWings(); //写死在rep中
	public Duck() { f = new FlyWithWings(); } //写死在构造方法中
	public void fly(){ f.fly(); }
}

参考文献:https://blog.csdn.net/weixin_44940258

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值