安居多伦多
  • 多市生活
    • 多市生活
    • 加国税务
    • 旅游度假
    • 生活安全
    • 行车安全
    • 窍门集锦
  • 多市书苑
    • 热门
    • 小说
    • 教育
  • 家居信息
    • 家居信息
    • 房屋保养
    • 房屋贷款
    • 房屋租赁
    • 房屋建筑
    • 房前屋后
    • 家居风水
  • 健康保健
    • 健康保健
    • 饮食起居
    • 食品安全
    • 健身锻炼
  • 书苑账户
    • 书苑登入
    • 书苑注册
    • 忘记书苑密码
    • 书苑账户信息
    • 关于我们
    • 联系我们
    • 隐私政策
多伦多书苑
在线书籍:随时阅读,随身听书。
所有书籍 | 人文 | 人物 | 人生 | 健康 | 儿童 | 医学 | 历史 | 历史 | 古典 | 哲学宗教 | 商业 | 外国 | 寓言 | 小说 | 教育 | 风水 | 管理 | 语言 |
为使本公益资源网站能继续提供免费阅读,请勿屏蔽广告。谢谢!报告弹出广告被滥用。
  1. 安居多伦多
  2. 网上书苑
  3. IT
  4. 设计模式之禅

设计模式之禅

2021-08-04 1人点赞 0条评论
点赞
x
语速1.0: 2.0
进度0:

上一页   |   返回目录   |   下一页

本书仅供会员,测试期间不限,赶快看。

4.2 美女何其多,观点各不同

我们举例来说明接口隔离原则到底对我们提出了什么要求。现在男生对小姑娘的称呼,使用频率最高的应该是“美女”了吧,你在大街上叫一声:“嗨,美女!”估计10个有8个回头,其中包括那位著名的如花。美女的标准各不相同,首先就需要定义一下什么是美女:首先要面貌好看,其次是身材要窈窕,然后要有气质,当然了,这三者各人的排列顺序不一样,总之要成为一名美女就必须具备:面貌、身材和气质,我们用类图体现一下星探(当然,你也可以把自己想象成星探)找美女的过程,如图4-1所示。

星探寻找美女的类图

图4-1 星探寻找美女的类图

定义了一个IPettyGirl接口,声明所有的美女都应该有goodLooking、niceFigure和great-Temperament,然后又定义了一个抽象类AbstractSearcher,其作用就是搜索美女并显示其信息,只要美女都按照这个规范定义,Searcher(星探)就轻松多了,美女类的实现如代码清单4-1所示。

代码清单4-1 美女类

public interface IPettyGirl {
//要有姣好的面孔
public void goodLooking();
//要有好身材
public void niceFigure();
//要有气质
public void greatTemperament();
}

美女的标准定义完毕,具体的美女实现类如代码清单4-2所示。

代码清单4-2 美女实现类

public class PettyGirl implements IPettyGirl {
private String name;
//美女都有名字
public PettyGirl(String _name) {
this.name=_name;
}
//脸蛋漂亮
public void goodLooking() {
System.out.println(this.name + "---脸蛋很漂亮!");
}
//气质要好
public void greatTemperament() {
System.out.println(this.name + "---气质非常好!");
}
//身材要好
public void niceFigure() {
System.out.println(this.name + "---身材非常棒!");
}
}

通过三个方法,把对美女的要求都定义出来了,按照这个标准,如花姑娘被排除在美女标准之外了。有美女,就有搜索美女的星探,其具体实现如代码清单4-3所示。

代码清单4-3 星探抽象类源代码

public abstract class AbstractSearcher {
protected IPettyGirl pettyGirl;
public AbstractSearcher(IPettyGirl _pettyGirl) {
this.pettyGirl = _pettyGirl;
}
//搜索美女,列出美女信息
public abstract void show();
}

星探的实现类就比较简单了,其源代码如代码清单4-4所示。

代码清单4-4 星探类

public class PettyGirl implements IPettyGirl {

private String name;
//美女都有名字

public PettyGirl(String _name) {
this.name=_name;
}
//脸蛋漂亮

public void goodLooking() {
System.out.println(this.name + "---脸蛋很漂亮!");
}
//气质要好

public void greatTemperament() {
System.out.println(this.name + "---气质非常好!");
}
//身材要好

public void niceFigure() {
System.out.println(this.name + "---身材非常棒!");
}
}

场景中的两个角色美女和星探都已经出现了,需要写一个场景类来串联起各个角色,场景类的实现如代码清单4-5所示。

代码清单4-5 场景类

public class Client {
//搜索并展示美女信息

public static void main(String[] args) {
//定义一个美女

IPettyGirl yanYan = new PettyGirl("嫣嫣");
AbstractSearcher searcher = new Searcher(yanYan);
searcher.show();
}
}

星探搜索美女的运行结果如下所示:

--------美女的信息如下:---------------
嫣嫣---脸蛋很漂亮!
嫣嫣---身材非常棒!
嫣嫣---气质非常好!

星探寻找美女的程序开发完毕了,运行结果也正确。我们回头来想想这个程序有没有问题,思考一下IPettyGirl这个接口,这个接口是否做到了最优化设计?答案是没有,还可以对接口进行优化。

我们的审美观点都在改变,美女的定义也在变化。唐朝的杨贵妃如果活在现在这个年代非羞愧而死不可,为什么?胖呀!但是胖并不影响她入选中国四大美女,说明当时的审美观与现在是有差异的。当然,随着时代的发展我们的审美观也在变化,当你发现有一个女孩,脸蛋不怎么样,身材也一般般,但是气质非常好,我相信大部分人都会把这样的女孩叫美女,审美素质提升了,就产生了气质型美女,但是我们的接口却定义了美女必须是三者都具备,按照这个标准,气质型美女就不能算美女,那怎么办?可能你要说了,我重新扩展一个美女类,只实现greatTemperament方法,其他两个方法置空,什么都不写,不就可以了吗?

聪明,但是行不通!为什么呢?星探AbstractSearcher依赖的是IPettyGirl接口,它有三个方法,你只实现了两个方法,星探的方法是不是要修改?我们上面的程序打印出来的信息少了两条,还让星探怎么去辨别是不是美女呢?

分析到这里,我们发现接口IPettyGirl的设计是有缺陷的,过于庞大了,容纳了一些可变的因素,根据接口隔离原则,星探AbstractSearcher应该依赖于具有部分特质的女孩子,而我们却把这些特质都封装了起来,放到了一个接口中,封装过度了!问题找到了,我们重新设计一下类图,修改后的类图如图4-2所示。

把原IPettyGirl接口拆分为两个接口,一种是外形美的美女IGoodBodyGirl,这类美女的特点就是脸蛋和身材极棒,超一流,但是没有审美素质,比如随地吐痰,文化程度比较低;另外一种是气质美的美女IGreatTemperamentGirl,谈吐和修养都非常高。我们把一个比较臃肿的接口拆分成了两个专门的接口,灵活性提高了,可维护性也增加了,不管以后是要外形美的美女还是气质美的美女都可以轻松地通过PettyGirl定义。两种类型的美女定义如代码清单4-6所示。

修改后的星探寻找美女类图

图4-2 修改后的星探寻找美女类图

代码清单4-6 两种类型的美女定义

public interface IGoodBodyGirl {
//要有姣好的面孔

public void goodLooking();
//要有好身材

public void niceFigure();
}

public interface IGreatTemperamentGirl {
//要有气质

public void greatTemperament();
}

按照脸蛋、身材、气质都具备才算美女,实现类实现两个接口,如代码清单4-7所示。

代码清单4-7 最标准的美女

public class PettyGirl implements IGoodBodyGirl,IGreatTemperamentGirl {

private String name;
//美女都有名字

public PettyGirl(String _name) {
this.name=_name;
}
//脸蛋漂亮

public void goodLooking() {
System.out.println(this.name + "---脸蛋很漂亮!");
}
//气质要好

public void greatTemperament() {
System.out.println(this.name + "---气质非常好!");
}
//身材要好

public void niceFigure() {
System.out.println(this.name + "---身材非常棒!");
}
}

通过这样的重构以后,不管以后是要气质美女还是要外形美女,都可以保持接口的稳定。当然,你可能要说了,以后可能审美观点再发生改变,只有脸蛋好看就是美女,那这个IGoodBody接口还是要修改的呀,确实是,但是设计是有限度的,不能无限地考虑未来的变更情况,否则就会陷入设计的泥潭中而不能自拔。

以上把一个臃肿的接口变更为两个独立的接口所依赖的原则就是接口隔离原则,让星探AbstractSearcher依赖两个专用的接口比依赖一个综合的接口要灵活。接口是我们设计时对外提供的契约,通过分散定义多个接口,可以预防未来变更的扩散,提高系统的灵活性和可维护性。

上一页   |   返回目录   |   下一页

类似书籍

设计冲刺:谷歌风投如何5天完成产品迭代
设计冲刺:谷歌风投如何5天完成产品迭代
数学之美和浪潮之巅
数学之美和浪潮之巅
SEO教程:搜索引擎优化入门与进阶(第3版)
SEO教程:搜索引擎优化入门与进阶(第3版)
人月神话
人月神话
Author:

标签: 暂无
最后更新:2021-08-04
< 上一篇
下一篇 >

本书评论

取消回复

©2021 安居多伦多 - 版权所有

本站由 好事来 Hostlike.com 提供技术支持。