面向对象-设计原则
2017-07-31 10:57
239 查看
1.设计原则-之Volley
(1)单一职责原则(S)
定义:一个类有多个方法,多个方法应是相关的,有共同的职责。
范围:适用于基础类,不适用于聚合类。聚合类应优先使用组合,再选择继承
Cache类:
1.获取缓存
2.添加缓存
3.初始化缓存
4.废除缓存
5.移除
(2) 开闭原则(O)
定义:对修改关闭,对扩展开放。(A调用B,对A修改关闭,对B扩展开放),
提供者B增加功能,调用者A不要修改代码。
范围:接口不变的情况之下
原因:减少变化
假如Cache还要拓展一个功能,XCache。那么调用者不要修改代码,提供者也不要修改原有存在代码,只要添加实现Cache类即可。
(3) 里氏替换(L)
定义:子类必须能替换成父类
原因:避免破坏继承结构
里氏替换原则通俗的来讲就是:子类可以扩展父类的功能,但不能改变父类原有的功能。它包含以下4层含义:
子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
子类中可以增加自己特有的方法。
当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。
看上去很不可思议,因为我们会发现在自己编程中常常会违反里氏替换原则,程序照样跑的好好的。所以大家都会产生这样的疑问,假如我非要不遵循里氏替换原则会有什么后果?
后果就是:你写的代码出问题的几率将会大大增加。
(4)接口隔离(I)
定义:客户端不要依赖他不需要的接口。接口细化
原因:如果依赖过多不用的方法,会导致一些不可预知的改变
(5) 依赖倒置:
定义:高层模块不应直接依赖底层模块,而是依赖抽象模块。
抽象不应依赖细节,细节必须依赖抽象
原因:高层模块依赖底层模块:高层模块调用底层方法。
高层模块依赖抽象:基于抽象层编程
底层模块依赖抽象:继承或实现抽象层
高层模块是业务复杂的模块,底层模块负责基本的原子操作。
Cache.java/** * An interface for a cache keyed by a String with a byte array as data. */ public interface Cache { /** * Retrieves an entry from the cache. * @param key Cache key * @return An {@link Entry} or null in the event of a cache miss */ public Entry get(String key); /** * Adds or replaces an entry to the cache. * @param key Cache key * @param entry Data to store and metadata for cache coherency, TTL, etc. */ public void put(String key, Entry entry); /** * Performs any potentially long-running actions needed to initialize the cache; * will be called from a worker thread. */ public void initialize(); /** * Invalidates an entry in the cache. * @param key Cache key * @param fullExpire True to fully expire the entry, false to soft expire */ public void invalidate(String key, boolean fullExpire); /** * Removes an entry from the cache. * @param key Cache key */ public void remove(String key); /** * Empties the cache. */ public void clear(); /** * Data and metadata for an entry returned by the cache. */ public static class Entry { /** The data returned from cache. */ public byte[] data; /** ETag for cache coherency. */ public String etag; /** Date of this response as reported by the server. */ public long serverDate; /** TTL for this record. */ public long ttl; /** Soft TTL for this record. */ public long softTtl; /** Immutable response headers as received from server; must be non-null. */ public Map<String, String> responseHeaders = Collections.emptyMap(); /** True if the entry is expired. */ public boolean isExpired() { return this.ttl < System.currentTimeMillis(); } /** True if a refresh is needed from the original data source. */ public boolean refreshNeeded() { return this.softTtl < System.currentTimeMillis(); } } }
Network.java
ResponseDelivery.java
CacheDispatcher.java 缓存调度,高层模块不依赖细节,全是依赖抽象编程
都是依赖抽象
参考文章:
http://blog.csdn.net/zhengzhb/article/details/7281833
(1)单一职责原则(S)
定义:一个类有多个方法,多个方法应是相关的,有共同的职责。
范围:适用于基础类,不适用于聚合类。聚合类应优先使用组合,再选择继承
Cache类:
1.获取缓存
2.添加缓存
3.初始化缓存
4.废除缓存
5.移除
/** * An interface for a cache keyed by a String with a byte array as data. */ public interface Cache { /** * Retrieves an entry from the cache. * @param key Cache key * @return An {@link Entry} or null in the event of a cache miss */ public Entry get(String key); /** * Adds or replaces an entry to the cache. * @param key Cache key * @param entry Data to store and metadata for cache coherency, TTL, etc. */ public void put(String key, Entry entry); /** * Performs any potentially long-running actions needed to initialize the cache; * will be called from a worker thread. */ public void initialize(); /** * Invalidates an entry in the cache. * @param key Cache key * @param fullExpire True to fully expire the entry, false to soft expire */ public void invalidate(String key, boolean fullExpire); /** * Removes an entry from the cache. * @param key Cache key */ public void remove(String key); /** * Empties the cache. */ public void clear(); /** * Data and metadata for an entry returned by the cache. */ public static class Entry { /** The data returned from cache. */ public byte[] data; /** ETag for cache coherency. */ public String etag; /** Date of this response as reported by the server. */ public long serverDate; /** TTL for this record. */ public long ttl; /** Soft TTL for this record. */ public long softTtl; /** Immutable response headers as received from server; must be non-null. */ public Map<String, String> responseHeaders = Collections.emptyMap(); /** True if the entry is expired. */ public boolean isExpired() { return this.ttl < System.currentTimeMillis(); } /** True if a refresh is needed from the original data source. */ public boolean refreshNeeded() { return this.softTtl < System.currentTimeMillis(); } } }
(2) 开闭原则(O)
定义:对修改关闭,对扩展开放。(A调用B,对A修改关闭,对B扩展开放),
提供者B增加功能,调用者A不要修改代码。
范围:接口不变的情况之下
原因:减少变化
public static RequestQueue newRequestQueueInDisk(Context context, String dir, HttpStack stack) { File cacheDir = new File(dir, DEFAULT_CACHE_DIR); String userAgent = "volley/0"; try { String packageName = context.getPackageName(); PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0); userAgent = packageName + "/" + info.versionCode; } catch (NameNotFoundException e) { } if (stack == null) { if (Build.VERSION.SDK_INT >= 9) { stack = new HurlStack(); } else { // Prior to Gingerbread, HttpUrlConnection was unreliable. // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent)); } } Network network = new BasicNetwork(stack); //对修改关闭,对拓展开放 Cache cache = new DiskBasedCache(cacheDir);//对修改关闭,对拓展开放 RequestQueue queue = new RequestQueue(cache, network); queue.start(); return queue; }
假如Cache还要拓展一个功能,XCache。那么调用者不要修改代码,提供者也不要修改原有存在代码,只要添加实现Cache类即可。
(3) 里氏替换(L)
定义:子类必须能替换成父类
原因:避免破坏继承结构
里氏替换原则通俗的来讲就是:子类可以扩展父类的功能,但不能改变父类原有的功能。它包含以下4层含义:
子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
子类中可以增加自己特有的方法。
当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。
看上去很不可思议,因为我们会发现在自己编程中常常会违反里氏替换原则,程序照样跑的好好的。所以大家都会产生这样的疑问,假如我非要不遵循里氏替换原则会有什么后果?
后果就是:你写的代码出问题的几率将会大大增加。
(4)接口隔离(I)
定义:客户端不要依赖他不需要的接口。接口细化
原因:如果依赖过多不用的方法,会导致一些不可预知的改变
(5) 依赖倒置:
定义:高层模块不应直接依赖底层模块,而是依赖抽象模块。
抽象不应依赖细节,细节必须依赖抽象
原因:高层模块依赖底层模块:高层模块调用底层方法。
高层模块依赖抽象:基于抽象层编程
底层模块依赖抽象:继承或实现抽象层
高层模块是业务复杂的模块,底层模块负责基本的原子操作。
public class RequestQueue { /** Used for generating monotonically-increasing sequence numbers for requests. */ //http://www.cnblogs.com/baizhanshi/p/5662376.html 原子操作,硬件保障 private AtomicInteger mSequenceGenerator = new AtomicInteger(); /** * Staging area for requests that already have a duplicate request in flight. * 为什呢要给请求分段,是因为他在队列中有一个重复的请求 * <ul> * <li>containsKey(cacheKey) indicates that there is a request in flight for the given cache * key.</li> * <li>get(cacheKey) returns waiting requests for the given cache key. The in flight request * is <em>not</em> contained in that list. Is null if no requests are staged.</li> * </ul> */ private final Map<String, Queue<Request>> mWaitingRequests = new HashMap<String, Queue<Request>>(); /** * The set of all requests currently being processed by this RequestQueue. A Request * will be in this set if it is waiting in any queue or currently being processed by * any dispatcher. */ private final Set<Request> mCurrentRequests = new HashSet<Request>(); /** The cache triage queue. */ private final PriorityBlockingQueue<Request> mCacheQueue = new PriorityBlockingQueue<Request>(); /** The queue of requests that are actually going out to the network. */ private final PriorityBlockingQueue<Request> mNetworkQueue = new PriorityBlockingQueue<Request>(); /** Number of network request dispatcher threads to start. */ private static final int DEFAULT_NETWORK_THREAD_POOL_SIZE = 4; /** Cache interface for retrieving and storing respones. */ private final Cache mCache; /** Network interface for performing requests. */ private final Network mNetwork; /** Response delivery mechanism. */ private final ResponseDelivery mDelivery; /** The network dispatchers. */ private NetworkDispatcher[] mDispatchers; /** The cache dispatcher. */ private CacheDispatcher mCacheDispatcher; /** * Creates the worker pool. Processing will not begin until {@link #start()} is called. * * @param cache A Cache to use for persisting responses to disk * @param network A Network interface for performing HTTP requests * @param threadPoolSize Number of network dispatcher threads to create * @param delivery A ResponseDelivery interface for posting responses and errors * 传递响应和错误信息 */ public RequestQueue(Cache cache, Network network, int threadPoolSize, ResponseDelivery delivery) { mCache = cache; mNetwork = network; mDispatchers = new NetworkDispatcher[threadPoolSize]; mDelivery = delivery; }
Cache.java/** * An interface for a cache keyed by a String with a byte array as data. */ public interface Cache { /** * Retrieves an entry from the cache. * @param key Cache key * @return An {@link Entry} or null in the event of a cache miss */ public Entry get(String key); /** * Adds or replaces an entry to the cache. * @param key Cache key * @param entry Data to store and metadata for cache coherency, TTL, etc. */ public void put(String key, Entry entry); /** * Performs any potentially long-running actions needed to initialize the cache; * will be called from a worker thread. */ public void initialize(); /** * Invalidates an entry in the cache. * @param key Cache key * @param fullExpire True to fully expire the entry, false to soft expire */ public void invalidate(String key, boolean fullExpire); /** * Removes an entry from the cache. * @param key Cache key */ public void remove(String key); /** * Empties the cache. */ public void clear(); /** * Data and metadata for an entry returned by the cache. */ public static class Entry { /** The data returned from cache. */ public byte[] data; /** ETag for cache coherency. */ public String etag; /** Date of this response as reported by the server. */ public long serverDate; /** TTL for this record. */ public long ttl; /** Soft TTL for this record. */ public long softTtl; /** Immutable response headers as received from server; must be non-null. */ public Map<String, String> responseHeaders = Collections.emptyMap(); /** True if the entry is expired. */ public boolean isExpired() { return this.ttl < System.currentTimeMillis(); } /** True if a refresh is needed from the original data source. */ public boolean refreshNeeded() { return this.softTtl < System.currentTimeMillis(); } } }
Network.java
/** * An interface for performing requests. */ public interface Network { /** * Performs the specified request. * @param request Request to process * @return A {@link NetworkResponse} with data and caching metadata; will never be null * @throws VolleyError on errors */ public NetworkResponse performRequest(Request<?> request) throws VolleyError; }
ResponseDelivery.java
public interface ResponseDelivery { /** * Parses a response from the network or cache and delivers it. */ public void postResponse(Request<?> request, Response<?> response); /** * Parses a response from the network or cache and delivers it. The provided * Runnable will be executed after delivery. */ public void postResponse(Request<?> request, Response<?> response, Runnable runnable); /** * Posts an error for the given request. */ public void postError(Request<?> request, VolleyError error); }
CacheDispatcher.java 缓存调度,高层模块不依赖细节,全是依赖抽象编程
public class CacheDispatcher extends Thread { private static final boolean DEBUG = VolleyLog.DEBUG; /** The queue of requests coming in for triage. */ private final BlockingQueue<Request> mCacheQueue; /** The queue of requests going out to the network. */ private final BlockingQueue<Request> mNetworkQueue; /** The cache to read from. */ private final Cache mCache; /** For posting responses. */ private final ResponseDelivery mDelivery; /** Used for telling us to die. */ private volatile boolean mQuit = false; /** * Creates a new cache triage dispatcher thread. You must call {@link #start()} * in order to begin processing. * * @param cacheQueue Queue of incoming requests for triage * @param networkQueue Queue to post requests that require network to * @param cache Cache interface to use for resolution * @param delivery Delivery interface to use for posting responses */ public CacheDispatcher( BlockingQueue<Request> cacheQueue, BlockingQueue<Request> networkQueue, Cache cache, ResponseDelivery delivery) { mCacheQueue = cacheQueue; mNetworkQueue = networkQueue; mCache = cache; mDelivery = delivery; } /** * Forces this dispatcher to quit immediately. If any requests are still in * the queue, they are not guaranteed to be processed. */ public void quit() { mQuit = true; interrupt(); } @Override public void run() { if (DEBUG) VolleyLog.v("start new dispatcher"); Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);//设置进程优先级 // Make a blocking call to initialize the cache. //初始化缓存 mCache.initialize(); while (true) { try { // Get a request from the cache triage queue, blocking until // at least one is available. //从缓存队列中取一个可以用的 final Request request = mCacheQueue.take(); request.addMarker("cache-queue-take"); // If the request has been canceled, don't bother dispatching it. //如果request已经被取消,不要打扰到传递 if (request.isCanceled()) { request.finish("cache-discard-canceled"); continue; } // Attempt to retrieve this item from cache. //取回缓存 Cache.Entry entry = mCache.get(request.getCacheKey()); if (entry == null) { request.addMarker("cache-miss"); // Cache miss; send off to the network dispatcher. //缓存不存在,则加入到网络请求队列中 mNetworkQueue.put(request); continue; } // If it is completely expired, just send it to the network. //如果缓存过期了,则加入到网络请求队列中 if (entry.isExpired()) { request.addMarker("cache-hit-expired"); request.setCacheEntry(entry); mNetworkQueue.put(request); continue; } // We have a cache hit; parse its data for delivery back to the request. //我们找到了cache(不过期,没取消),解析数据传递到请求中区 request.addMarker("cache-hit"); Response<?> response = request.parseNetworkResponse( new NetworkResponse(entry.data, entry.responseHeaders)); request.addMarker("cache-hit-parsed"); if (!entry.refreshNeeded()) { // Completely unexpired cache hit. Just deliver the response. //获取到没过期的缓存,传输这个响应 mDelivery.postResponse(request, response); } else { // Soft-expired cache hit. We can deliver the cached response, // but we need to also send the request to the network for // refreshing. //缓存需要刷新 request.addMarker("cache-hit-refresh-needed"); request.setCacheEntry(entry); // Mark the response as intermediate. response.intermediate = true; // Post the intermediate response back to the user and have // the delivery then forward the request along to the network. //缓存过期之后,把请求放入到网络队列中去 mDelivery.postResponse(request, response, new Runnable() { @Override public void run() { try { //加入到网络队列里面去 mNetworkQueue.put(request); } catch (InterruptedException e) { // Not much we can do about this. } } }); } } catch (InterruptedException e) { // We may have been interrupted because it was time to quit. if (mQuit) { return; } continue; } } } }
都是依赖抽象
参考文章:
http://blog.csdn.net/zhengzhb/article/details/7281833
相关文章推荐
- 面向对象设计原则之一--开闭原则
- 61条Java面向对象设计的经验原则
- 面向对象的设计原则
- 面向对象设计的SOLID原则
- 面向对象设计七大原则
- 程序员应该了解的面向对象七大设计原则
- 面向对象设计原则--面试遭遇
- 面向对象的设计原则(整理于敏捷开发)
- 面向对象设计原则之单一职责原则
- 面向对象设计原则-liskov替换原则
- 面向对象设计原则--《敏捷软件开发》读书笔记
- 面向对象设计的SOLID原则
- 面向对象设计原则-Principles and Patterns读书笔记三
- 面向对象重要设计原则概述
- 面向对象的设计原则(JAVA)
- 面向对象设计原则与设计模式
- 面向对象设计的6大原则!
- 面向对象设计原则——开放关闭原则
- 面向对象软件设计原则
- 面向对象设计原则