打字猴:1.70048365e+09
1700483650
1700483651 问题发现了,就要想办法解决。再回顾一下编写的代码,注意看findUserByAgeThan和findUserByNameEqual两个方法,两者的代码有什么不同呢?除了if后面的判断条件不同外,就没有不同的地方了,我们一直在说封装变化,这两段程序就仅仅有这一个变化点,我们是不是可以把它封装起来呢?完全可以,把它们两者的共同点抽取出来,先修改一下接口,如代码清单37-5所示。
1700483652
1700483653 代码清单37-5 修正后的接口
1700483654
1700483655 public interface IUserProvider{
1700483656
1700483657 //根据条件查找用户
1700483658
1700483659 public ArrayList<User>findUser(boolean condition);
1700483660
1700483661 }
1700483662
1700483663 这个接口的设计想法非常好,但是参数condition很难实现,看看findUserByAgeThan、findUserByNameEqual这两个方法,怎么才能把两者的不同点设置成一个布尔型呢?如果需要在IUserProvider对象外判断后传递进来,那我们的封装就没有任何意义了——目前为止,这个方案有问题了。
1700483664
1700483665 继续考虑,既然不能在封装外运算,那就把整个条件都进行封装,由IUserProvider自己实现运算。好方法!那我们就设计一个这样的类,我们叫它规格类,什么意思呢?它是对一批对象的说明性描述,它依照基准判断候选对象是否满足条件。思考后,我们设计出类图,如图37-2所示。
1700483666
1700483667
1700483668
1700483669
1700483670 图37-2 加入规格后的设计类图
1700483671
1700483672 在该类图中建立了一个规格书接口,它的作用就是定制各种各样的规格,比如名字相等的规格UserByNameEqual、年龄大于基准年龄的规格UserByAgeThan等等,然后在用户操作类中采用该规格进行判断。User类没有任何改变,如代码清单37-1所示,不再赘述。
1700483673
1700483674 规格书接口是对全体规格书的声明定义,如代码清单37-6所示。
1700483675
1700483676 代码清单37-6 规格书接口
1700483677
1700483678 public interface IUserSpecification{
1700483679
1700483680 //候选者是否满足要求
1700483681
1700483682 public boolean isSatisfiedBy(User user);
1700483683
1700483684 }
1700483685
1700483686 规格书接口只定义一个方法,判断候选用户是否满足条件。再来看姓名相同的规格书,它实现了规格书接口,如代码清单37-7所示。
1700483687
1700483688 代码清单37-7 姓名相同的规格书
1700483689
1700483690 public class UserByNameEqual implements IUserSpecification{
1700483691
1700483692 //基准姓名
1700483693
1700483694 private String name;
1700483695
1700483696 //构造函数传递基准姓名
1700483697
1700483698 public UserByNameEqual(String_name){
1700483699
[ 上一页 ]  [ :1.70048365e+09 ]  [ 下一页 ]