面向接口的设计 比我以往任何时候都更好地描述了这一点 http://pragprog.com/titles/kpiod/interface-oriented-design。作者使用了一些很好的接口与继承的例子,比如动物王国的分类学。迄今为止,它有一些反对过度继承和明智使用接口的最佳论据。
一堆以不兼容的方式提出它们的网站:
Facebook.java列表:
public class Facebook {
public void showFacebook() {
// ...
}
}
YouTube.java 列表:
public class YouTube {
public void showYouTube() {
// ...
}
}
StackOverflow.java的列表:
public class StackOverflow {
public void showStackOverflow() {
// ...
}
}
客户端手动处理网站用来带来的不同方法
自己起来:
ClientWithoutInterface.java的列表:
public class ClientWithoutInterface {
public static void main(String... args) {
String websiteRequested = args[0];
if ("facebook".equals(websiteRequested)) {
new Facebook().showFacebook();
} else if ("youtube".equals(websiteRequested)) {
new YouTube().showYouTube();
} else if ("stackoverflow".equals(websiteRequested)) {
new StackOverflow().showStackOverflow();
}
}
}
引入网站界面,让客户的工作更轻松:
Website.java的列表:
public interface Website {
void showWebsite();
}
Facebook.java列表:
public class Facebook implements Website {
public void showWebsite() {
// ...
}
}
YouTube.java 列表:
public class YouTube implements Website {
public void showWebsite() {
// ...
}
}
StackOverflow.java的列表:
public class StackOverflow implements Website {
public void showWebsite() {
// ...
}
}
ClientWithInterface.java的列表:
public class ClientWithInterface {
public static void main(String... args) {
String websiteRequested = args[0];
Website website;
if ("facebook".equals(websiteRequested)) {
website = new Facebook();
} else if ("youtube".equals(websiteRequested)) {
website = new YouTube();
} else if ("stackoverflow".equals(websiteRequested)) {
website = new StackOverflow();
}
website.showWebsite();
}
}
哎呀,没有更多的代码?其实我们可以走得更远一点
让客户邀请几个朋友帮助它找到并渲染
请求的网站:
ClientWithALittleHelpFromFriends.java 列表:
public class ClientWithALittleHelpFromFriends {
public static void main(String... args) {
WebsiteFinder finder = new WebsiteFinder();
WebsiteRenderer renderer = new WebsiteRenderer();
renderer.render(finder.findWebsite(args[0]));
}
}
WebsiteFinder.java的列表:
public class WebsiteFinder {
public Website findWebsite(String websiteRequested) {
if ("facebook".equals(websiteRequested)) {
return new Facebook();
} else if ("youtube".equals(websiteRequested)) {
return new YouTube();
} else if ("stackoverflow".equals(websiteRequested)) {
return new StackOverflow();
}
}
}
WebsiteRenderer.java的列表:
public class WebsiteRenderer {
public void render(Website website) {
website.showWebsite();
}
}
回顾ClientWithoutInterface,它完全耦合到特定的查找和基于渲染。当您访问数百或数千个站点时,将很难管理。有了 Website 界面,WebsiteFinder 可以轻松转换为支持地图、数据库甚至基于 Web 的查找,以满足不断扩大的规模。
接口可以将角色与实现它的组件分开。它们使得基于几乎任何东西交换相同问题的替代解决方案成为可能:
机器上的当前负载
数据集的大小(可以选择排序算法)
用户请求正在执行的操作