上次,我们从Guitar类中分离出了GuitarSpec类,可以让用户通过GuitarSpec类来搜索心仪的吉他。
这次用户说了,卖吉他的时候,又多出了一个搜索方法,弦的个数,可以从1到12,我不管反正我就要这个搜索功能,你看着办吧!
上次的GuitarSpec类中,我们并没有提供用户弦的个数这个搜索功能,于是乎,我们在GuitarSpec类中加上一个变量numStrings来存储弦的个数:
GuitarSpec.java更新:
这不算完,有没有想到在Inventory.java的search()方法中我们没有比对numStrings这个属性,所以我们也要去比对。
等等,对象与对象之间说好的老死不相往来呢?低耦合:代码中,各个对象各有特定的工作要做,而且只做那项工作,因此,代码的功能被分散给许多定义良好的对象,它们各自将单一工作做的很好。
低耦合好处,一个对象的更新,不影响其他对象。比如你长高了,全世界的人都跟着一起长高了,想想都感到兴奋!
所以,我们要做的是,更新GuitarSpec类中变量,对Inventory类没有任何影响。
不行,怎么会没有影响呢?对比方法就在search()中。
有没有想过将对比的方法从search()分离出来?
请问分离出来放哪里好呢?
既然我们更新GuitarSpec类中变量,对比的方法也跟着增加,就放在GuitarSpec类中吧。
下面我们要讲的是:委托(delegation):
Inventory的对象在search()中为了找到匹配吉他,就要去Guitar库中和用户的搜索信息进行对比。
现在,我们把对比方法给了GuitarSpec,那只有让Inventory对象去求GuitarSpec的对象,让它去完成自己完不成的任务。
好,这就是委托,自己完不成的任务,交给其他 能完成这个任务的人 来完成这个任务! 好绕口。
来个简单的,我们要学会托人去办事。
现在我们再来更新GuitarSpec类,让它实现对比功能:
1 package com.headfirst.guitar; 2 3 public class GuitarSpec { 4 Builder builder; 5 String model; 6 Type type; 7 Wood backWood; 8 Wood topWood; 9 int numStrings; 10 11 12 public GuitarSpec(Builder builder, String model, Type type, Wood backWood, Wood topWood){ 13 this.builder = builder; 14 this.model = model; 15 this.type = type; 16 this.backWood = backWood; 17 this.topWood = topWood; 18 this.numStrings = numStrings; 19 } 20 21 public Builder getBuilder(){ 22 return this.builder; 23 } 24 25 public String getModel(){ 26 return this.model; 27 } 28 29 public Type getType(){ 30 return this.type; 31 } 32 33 public Wood getBackWood(){ 34 return this.backWood; 35 } 36 37 public Wood getTopWood(){ 38 return this.topWood; 39 } 40 41 public int getNumStrings(){ 42 return this.numStrings; 43 } 44 45 public boolean matches(GuitarSpec otherSpec){ 46 if(builder != otherSpec.builder) 47 return false; 48 if((model != null) && (!model.equals("")) && 49 (!model.equalsIgnoreCase(otherSpec.model))) 50 return false; 51 if(type != otherSpec.type) 52 return false; 53 if(numStrings != otherSpec.numStrings) 54 return false; 55 if(backWood != otherSpec.backWood) 56 return false; 57 if(topWood != otherSpec.topWood) 58 return false; 59 60 return true; 61 } 62 }
Inventory.java中search()方法更新:
1 public List search(GuitarSpec searchGuitar){ 2 List matchingGuitars = new LinkedList(); 3 for(Iterator i = guitars.iterator(); i.hasNext();){ 4 Guitar guitar = (Guitar) i.next(); 5 if(guitar.getGuitarSpec().matches(searchGuitar)) 6 matchingGuitars.add(guitar); 7 } 8 9 return matchingGuitars; 10 }
从此以后,增加新的搜索变量,只要修改GuitarSpec类就可以了。
其实委托最好的解释就是,equals()这个方法:
不是在方法之中比较两个对象是否相等,而是调用两个对象之一的equals()方法并传入第二个对象,接着从equals()方法得到true或false的响应。