组合和继承,是很基础的两种设计模式,甚至在没有听说过任何设计模式的时候,就已经用上了这种模式。这两种模式也被称为最基础的设计模式。但是在真实的使用过程中,一些初学者并不能很好的使用这两种设计模式,尤其是在两者混合使用的时候,可能会出现更多的问题。
字面上理解组合和继承,并没有太多的差别。但是如何在设计过程中用简单的理论,创造出经典的设计,又是另外一码事儿了。下面就根据开源的代码,看看高手是如何写代码的。
代码来源:httpclient代码。
整体代码可以从上面提供的地址下载,文中之引用关键代码,只做说清关系的作用。
我们的程序在运行过程中(尤其是有多个线程的时候),通常需要一个上下文来保存运行过程中的中间值和一些配置参数。在不同的情景下,可能需要不同的上下文体。这个时候,如何设计一种扩展性强的上下文实现,就成了一个问题。
首先,我们需要一个HttpClientContext,如何让这个类变得上下可扩展,让我们看看大牛们是怎么写代码的。
public class HttpClientContext extends HttpCoreContext 。其中HttpClientContext是我们在某种情况下需要的一个Context类,为了向上抽象,构建了一个顶层的核心上下文。
下面是httpCoreContext的定义
public class HttpCoreContext implements HttpContext。HttpContext接口,是上下文在使用过程中需要引用的接口。
简单的讲,这样实现了多态,只要重写CoreContext里面的方法,就可以动态的改变Context的功能。但是这样明显显得灵活性不够。因为不同的Context类之间的差别度(差异化的程度)可能不是很大。这样可能会造成很多的冗余代码,并且Context和业务相关,这个在开发及维护方面,显得有一些缺陷。
上面说的是继承,单独的继承,虽然有可扩展性,但是明显的显得不足。
看看下面的代码
public static HttpCoreContext create() {
return new HttpCoreContext(new BasicHttpContext());
}
public static HttpCoreContext adapt(final HttpContext context) {
Args.notNull(context, "HTTP context");
if (context instanceof HttpCoreContext) {
return (HttpCoreContext) context;
} else {
return new HttpCoreContext(context);
}
}
private final HttpContext context;
public HttpCoreContext(final HttpContext context) {
super();
this.context = context;
}
这是HttpCoreContext的几种创建方法,这段代码,起到了相当大的作用
public HttpCoreContext(final HttpContext context) {
super();
this.context = context;
}
运用组合的方式,大大提高了上下文类的扩展性。这样,如果你想构造一个个性化的上下文,你只需将实现了HttpContext接口的类以参数的形式构造为HttpCoreContext的任意子类即可。如果所需要的上下文类有个性化的方法,只要在拿到上下文之后,进行向下转型即可。这样就大大提高了该上下文的可扩展性。
高手的代码,总让人回味无穷。高手也像武侠小说中那样,将最简单的招式,化腐朽为神奇,以别人想不到的方式,作出独具匠心的设计。