抽象建立的这层间接性,解除了调用者与实现类之间的具体依赖,使得实现类可以单独变化,而不会影响到调用者。例如,当我们需要为元数据的读取操作定义对象时,好的编码习惯是为其定义一个接口:
public
interface MetadataReaderService {
public MetadataObject getMetadataObject(String metadataName);
public MetadataField getMetadataField(
String tableName,String fieldName);
public MetadataRelation getMetadatarelation(
long objectId,long relateObjectId);
}
MetadataReaderServiceImpl类实现了MetadataReaderService接口,在实现中通过注入数据访问对象,完成对元数据信息的读取:
public
class MetadataReaderServiceImpl implements
MetadataReaderService {
private MetadataObjectDAO metadataObjectDAO;
private MetadataFieldDAO metadataFieldDAO;
private MetadataRelationDAO metadataRelationDAO;
public MetadataObjectDAO getMetadataObjectDAO() {
return metadataObjectDAO;
}
public
void setMetadataObjectDAO(
MetadataObjectDAO metadataObjectDAO) {
this.metadataObjectDAO = metadataObjectDAO;
}
public MetadataFieldDAO getMetadataFieldDAO() {
return metadataFieldDAO;
}
public MetadataObject getMetadataObject(String metadataName) {
QuerySqlStatementImpl {
public MetadataReaderService getMetadataReader() {
return
this.metadataReaderService;
}
public
void setMetadataReader(MetadataReaderService reader) {
this.metadataReaderService = reader;
}
private String generateJoinStatement(TableNode rootTableNode){
String metadataName = rootTableNode.getMetadataName();
MetadataObject rootMetadataObject
=
this.getMetadataReader().getMetadataObject(metadataName);
}
}
public
class CachedMetadataReaderService implements
MetadataReaderService{
private MetadataReaderService readerService;
private MetadataCacheManager cacheManager;
@Override
public MetadataObject getMetadataObject(String metadataName) {
Serializable obj = cacheManager.getObjectCached(metadataName);
if(obj!=null){
return (MetadataObject) obj;
}else{
MetadataObject metadataObject = readerService.
getMetadataObject(metadataName);
cacheManager.putObjectCached(metadataName,
(Serializable) metadataObject);
return metadataObject;
}
}
}
CachedMetadataReaderService类相当于RealMetadataReaderService的代理,由它决定是从缓存获取,还是从数据库中获取。现在,我们可以让调用者访问CachedMetadataReaderService类。因为它与RealMetadataReaderService同属于一个共同的接口,所以调用者察觉不到变化。为了解除创建具体对象的依赖,我们还可以使用IoC容器,利用依赖注入的方式注入调用者需要的对象。正是因为MetadataReaderService接口的存在,当面对需求发生变化时,我们只做了两件事:扩展增加了CachedMetadataReaderService类;修改Spring的配置文件。对于原有的代码,无论是服务的提供者还是调用者,都没有受到任何影响。接口引入的间接性,无疑是能够拥抱变化的。