Glide源码阅读之策略模式1【DiskCacheStrategy】
定义
《大话设计模式》|策略模式
策略模式(Strategy):定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
Glide|DiskCacheStrategy
包路径:com.bumptech.glide.load.engine.DiskCacheStrategy
/** Set of available caching strategies for media. */
public abstract class DiskCacheStrategy {
/**
* Returns true if this request should cache the original unmodified data.
*
* @param dataSource Indicates where the data was originally retrieved.
*/
如果此请求应该缓存原始未修改的数据,则返回true。
参数:
dataSource -指示最初检索数据的位置。
public abstract boolean isDataCacheable(DataSource dataSource);
/**
* Returns true if this request should cache the final transformed resource.
*
* @param isFromAlternateCacheKey {@code true} if the resource we've decoded was loaded using an
* alternative, rather than the primary, cache key.
* @param dataSource Indicates where the data used to decode the resource was originally
* retrieved.
* @param encodeStrategy The {@link EncodeStrategy} the {@link
* com.bumptech.glide.load.ResourceEncoder} will use to encode the resource.
*/
如果此请求缓存最终转换的资源,则返回true。
参数:
isFromAlternateCacheKey -如果我们已经解码的资源是使用替代的缓存键加载的,而不是主缓存键,则为true。
dataSource -指示最初检索用于解码资源的数据的位置。
encodeStrategy - ResourceEncoder将使用encodeStrategy对资源进行编码。
public abstract boolean isResourceCacheable(
boolean isFromAlternateCacheKey, DataSource dataSource, EncodeStrategy encodeStrategy);
/** Returns true if this request should attempt to decode cached resource data. */
如果此请求应该尝试解码缓存的资源数据,则返回true。
public abstract boolean decodeCachedResource();
/** Returns true if this request should attempt to decode cached source data. */
如果此请求应该尝试解码缓存的源数据,则返回true。
public abstract boolean decodeCachedData();
}
一组可用的媒体缓存策略。
共有五种策略实现
- ALL
- NONE
- DATA
- RESOURCE
- AUTOMATIC
DiskCacheStrategy.ALL
使用data和RESOURCE缓存远程数据,仅使用RESOURCE缓存本地数据。
/**
* Caches remote data with both {@link #DATA} and {@link #RESOURCE}, and local data with {@link
* #RESOURCE} only.
*/
public static final DiskCacheStrategy ALL =
new DiskCacheStrategy() {
@Override
public boolean isDataCacheable(DataSource dataSource) {
return dataSource == DataSource.REMOTE;
}
@Override
public boolean isResourceCacheable(
boolean isFromAlternateCacheKey, DataSource dataSource, EncodeStrategy encodeStrategy) {
return dataSource != DataSource.RESOURCE_DISK_CACHE
&& dataSource != DataSource.MEMORY_CACHE;
}
@Override
public boolean decodeCachedResource() {
return true;
}
@Override
public boolean decodeCachedData() {
return true;
}
};
DiskCacheStrategy.NONE
不保存数据到缓存。
/** Saves no data to cache. */
public static final DiskCacheStrategy NONE =
new DiskCacheStrategy() {
@Override
public boolean isDataCacheable(DataSource dataSource) {
return false;
}
@Override
public boolean isResourceCacheable(
boolean isFromAlternateCacheKey, DataSource dataSource, EncodeStrategy encodeStrategy) {
return false;
}
@Override
public boolean decodeCachedResource() {
return false;
}
@Override
public boolean decodeCachedData() {
return false;
}
};
DiskCacheStrategy.DATA
在解码之前,将检索到的数据直接写入磁盘缓存。
/** Writes retrieved data directly to the disk cache before it's decoded. */
public static final DiskCacheStrategy DATA =
new DiskCacheStrategy() {
@Override
public boolean isDataCacheable(DataSource dataSource) {
return dataSource != DataSource.DATA_DISK_CACHE && dataSource != DataSource.MEMORY_CACHE;
}
@Override
public boolean isResourceCacheable(
boolean isFromAlternateCacheKey, DataSource dataSource, EncodeStrategy encodeStrategy) {
return false;
}
@Override
public boolean decodeCachedResource() {
return false;
}
@Override
public boolean decodeCachedData() {
return true;
}
};
DiskCacheStrategy.RESOURCE
将解码后的资源写入磁盘。
/** Writes resources to disk after they've been decoded. */
public static final DiskCacheStrategy RESOURCE =
new DiskCacheStrategy() {
@Override
public boolean isDataCacheable(DataSource dataSource) {
return false;
}
@Override
public boolean isResourceCacheable(
boolean isFromAlternateCacheKey, DataSource dataSource, EncodeStrategy encodeStrategy) {
return dataSource != DataSource.RESOURCE_DISK_CACHE
&& dataSource != DataSource.MEMORY_CACHE;
}
@Override
public boolean decodeCachedResource() {
return true;
}
@Override
public boolean decodeCachedData() {
return false;
}
};
DiskCacheStrategy.AUTOMATIC
根据DataFetcher的数据源和ResourceEncoder的EncodeStrategy(如果ResourceEncoder可用),尝试智能地选择策略。
/**
* Tries to intelligently choose a strategy based on the data source of the {@link
* com.bumptech.glide.load.data.DataFetcher} and the {@link
* com.bumptech.glide.load.EncodeStrategy} of the {@link com.bumptech.glide.load.ResourceEncoder}
* (if an {@link com.bumptech.glide.load.ResourceEncoder} is available).
*/
public static final DiskCacheStrategy AUTOMATIC =
new DiskCacheStrategy() {
@Override
public boolean isDataCacheable(DataSource dataSource) {
return dataSource == DataSource.REMOTE;
}
@Override
public boolean isResourceCacheable(
boolean isFromAlternateCacheKey, DataSource dataSource, EncodeStrategy encodeStrategy) {
return ((isFromAlternateCacheKey && dataSource == DataSource.DATA_DISK_CACHE)
|| dataSource == DataSource.LOCAL)
&& encodeStrategy == EncodeStrategy.TRANSFORMED;
}
@Override
public boolean decodeCachedResource() {
return true;
}
@Override
public boolean decodeCachedData() {
return true;
}
};
应用场景列表如下:
- 商场银行收银时促销,打折
- 诸葛亮的锦囊妙计,每一个锦囊就是一个策略
- 旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略
- JAVA AWT 中的 LayoutManager
Android里的应用场景:
布局策略如下:
- LinearLayout
- RelativeLayout
- FrameLayout
- DrawerLayout
- ConstraintLayout
- GridLayout
- 。。。
这些继承ViewGroup的xxxLayout布局方式就是一种布局实现策略。策略模式在Android系统源码里应用的也很频繁。
小计
策略模式用于迭代算法实现。作者也经常这么使用。使用场景很典型,实现上也比较容易
建议开发者把具体的复杂算法实现抽取出来进行策略模式实现。这样在进行算法改进的时候就很方便替换了
自研产品推荐
历时一年半多开发终于smartApi-v1.0.0版本在2023-09-15晚十点正式上线
smartApi是一款对标国外的postman的api调试开发工具,由于开发人力就作者一个所以人力有限,因此v1.0.0版本功能进行精简,大功能项有:
- api参数填写
- api请求响应数据展示
- PDF形式的分享文档
- Mock本地化解决方案
- api列表数据本地化处理
- 再加上UI方面的打磨
为了更好服务大家把之前的公众号和软件激活结合,如有疑问请大家反馈到公众号即可,下个版本30%以上的更新会来自公众号的反馈。
嗯!先解释不上服务端原因,API调试工具的绝大多数时候就是一个数据模型、数据处理、数据模型理解共识的问题解决工具,所以作者结合自己十多年开发使用的一些痛点来打造的,再加上服务端开发一般是面向企业的,作者目前没有精力和时间去打造企业服务。再加上没有资金投入所以服务端开发会滞后,至于什么时候会进行开发,这个要看募资情况和用户反馈综合考虑。虽然目前国内有些比较知名的api工具了,但作者使用后还是觉得和实际使用场景不符。如果有相关吐槽也可以在作者的公众号里反馈蛤!
下面是一段smartApi使用介绍: