Mybatis中使用到了哪些設計模式呢?下面就簡單的來介紹下:
1.構造者模式:
構造者模式是在mybatis初始化mapper映射文件的過程中,為<cache>節點創建Cache對象的方式就是構造者模式。其中CacheBilder為建造者角色,Cache對象是產品角色,可以看CacheBuilder的源碼來理解:
// 該類就是構造者
public class CacheBuilder {
// 這幾個屬性就是為生成產品對象需要的字段 private String id; private Class<? extends Cache> implementation; private List<Class<? extends Cache>> decorators; private Integer size; private Long clearInterval; private boolean readWrite; private Properties properties; public CacheBuilder(String id) { this.id = id; this.decorators = new ArrayList<Class<? extends Cache>>(); } // 以下這幾個方法就是構造者在生成產品對象時,需要使用到的幾個具體模塊方法。可以根據這幾個方法的不同組合,生成不同的Cache對象 public CacheBuilder implementation(Class<? extends Cache> implementation) { this.implementation = implementation; return this; } public CacheBuilder addDecorator(Class<? extends Cache> decorator) { if (decorator != null) { this.decorators.add(decorator); } return this; } public CacheBuilder size(Integer size) { this.size = size; return this; } public CacheBuilder clearInterval(Long clearInterval) { this.clearInterval = clearInterval; return this; } public CacheBuilder readWrite(boolean readWrite) { this.readWrite = readWrite; return this; } public CacheBuilder properties(Properties properties) { this.properties = properties; return this; } // 這個方法就是構造者生成產品的具體方法 返回的Cahce對象就是產品角色 public Cache build() { setDefaultImplementations(); Cache cache = newBaseCacheInstance(implementation, id); setCacheProperties(cache); if (PerpetualCache.class.equals(cache.getClass())) { // issue #352, do not apply decorators to custom caches for (Class<? extends Cache> decorator : decorators) { cache = newCacheDecoratorInstance(decorator, cache); setCacheProperties(cache); } cache = setStandardDecorators(cache); } return cache; } }
2 裝飾器模式
Cache接口的實現有多個,但是大部分都是裝飾器,只有PerpetualCache提供了Cache接口的基本實現,其他的裝飾器都是在PerpetualCache的基礎上提供了一些額外的功能,通過各種組合后滿足一個特定的需求。如圖:
先看下被裝飾者PerpetualCache的源碼部分:
private String id; // cache對象的唯一標識 // 底層使用HashMap來保存緩存信息 private Map<Object, Object> cache = new HashMap<Object, Object>(); public PerpetualCache(String id) { this.id = id; } public String getId() { return id; } public int getSize() { return cache.size(); } public void putObject(Object key, Object value) { cache.put(key, value); }
然后再看LruCache這個裝飾器:
private final Cache delegate; // 被裝飾的底層cache對象 private Map<Object, Object> keyMap; // LinkedHashMap 用於記錄key最近的使用情況 private Object eldestKey; // 記錄最少被使用的緩存項的key public LruCache(Cache delegate) { this.delegate = delegate; setSize(1024); }
3 工廠方法模式
mybatis中DataSource的創建使用了工廠方法模式,那么有哪些類在該模式中扮演了哪些角色呢?
工廠接口(Factory):DataSourceFactory扮演工廠接口角色
具體工廠類(ConcreteFactory):UnpooledDataSourceFactory和PooledDataSourceFactory
產品接口角色(Product):java.sql.DataSource
具體產品類角色(ConcreteFactory):UnpooledDataSource和PooledDataSource
可以用一張圖來表示這些關系和角色: