一,装饰者模式
总结:装饰者模式,就是对于父类A(Component),子类 B(ConcreteComponent)和C(Decorator)分别重新A中的方法,B中对方法进行实现,C及其子类可以调用B中实现的方法,也可以进行方法的拓展
二,代理模式
可以查看这篇文章,http://blog.csdn.net/luanlouis/article/details/24589193
https://www.zhihu.com/question/20794107
作者:雨夜偷牛的人
链接:https://www.zhihu.com/question/20794107/answer/23330381
来源:知乎
著作权归作者所有,转载请联系作者获得授权。
最近正好在看,特来挖坟。
关于动态代理设计模式很可能题主就在不知不觉中使用了,例如Spring中的AOP,Struts2中的拦截器等。
先来看静态代理模式代码:
package test;
public interface Subject
{
public void doSomething();
}
package test;
public class RealSubject implements Subject
{
public void doSomething()
{
System.out.println( "call doSomething()" );
}
}
package test;
public class SubjectProxy implements Subject
{
Subject subimpl = new RealSubject();
public void doSomething()
{
subimpl.doSomething();
}
}
package test;
public class TestProxy
{
public static void main(String args[])
{
Subject sub = new SubjectProxy();
sub.doSomething();
}
}
刚开始我会觉得SubjectProxy定义出来纯属多余,直接实例化实现类完成操作不就结了吗?后来随着业务庞大,你就会知道,实现proxy类对真实类的封装对于粒度的控制有着重要的意义。但是静态代理这个模式本身有个大问题,如果类方法数量越来越多的时候,代理类的代码量是十分庞大的。所以引入动态代理来解决此类问题。
先看代码:
package test;
public interface Subject
{
public void doSomething();
}
package test;
public class RealSubject implements Subject
{
public void doSomething()
{
System.out.println( "call doSomething()" );
}
}
package test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyHandler implements InvocationHandler
{
private Object tar;
//绑定委托对象,并返回代理类
public Object bind(Object tar)
{
this.tar = tar;
//绑定该类实现的所有接口,取得代理类
return Proxy.newProxyInstance(tar.getClass().getClassLoader(),
tar.getClass().getInterfaces(),
this);
}
public Object invoke(Object proxy , Method method , Object[] args)throws Throwable
{
Object result = null;
//这里就可以进行所谓的AOP编程了
//在调用具体函数方法前,执行功能处理
result = method.invoke(tar,args);
//在调用具体函数方法后,执行功能处理
return result;
}
}
public class TestProxy
{
public static void main(String args[])
{
ProxyHandler proxy = new ProxyHandler();
//绑定该类实现的所有接口
Subject sub = (Subject) proxy.bind(new RealSubject());
sub.doSomething();
}
}
看完代码,现在我来回答,动态代理的作用是什么:
- Proxy类的代码量被固定下来,不会因为业务的逐渐庞大而庞大;
- 可以实现AOP编程,实际上静态代理也可以实现,总的来说,AOP可以算作是代理模式的一个典型应用;
- 解耦,通过参数就可以判断真实类,不需要事先实例化,更加灵活多变。
三,工厂模式
http://blog.csdn.net/jason0539/article/details/23020989
工厂模式分为简单工厂模式,工厂方法模式和抽象工厂模式
简单工厂就是利用factory类创建对象,
抽象工厂是用多个factory创建对象,
四,原型模式
http://blog.csdn.net/sbsujjbcy/article/details/49302717
五,模板方法模式
在Android源码中,View中的Draw()方法就是一个“模板方法”。它定义了一系列“Draw”过程,主要包括这几个步骤(截取自源代码):
/*
* Draw traversal performs several drawing steps which must be executed
* in the appropriate order:
*
* 1. Draw the background
* 2. If necessary, save the canvas' layers to prepare for fading
* 3. Draw view's content
* 4. Draw children
* 5. If necessary, draw the fading edges and restore layers
* 6. Draw decorations (scrollbars for instance)
*/
在view类的draw()函数中调用了onDraw和dispatchDraw函数,当继承View子类中,如果要重写或者扩展这个方法时,整个方法流程和基本内容不能够修改,子类只能通过扩展onDraw(Canvas canvas)和dispatchDraw(Canvas canvas)两个函数,使子类自己的View显示效果和别的具体子类的不同。现在来看看继承自View类的具体子类如何扩展Draw()模板方法显示自己的与众不同:
TextView类中重写了OnDraw函数,SurfaceView重写了dispatchDraw()函数,ViewGroup类重写了dispatchDraw()函数。
根据模版方法中的方法,可以分为两大类:模版方法(Template Method)和基本方法(Primitive Method)。其中我们这里的例子Draw()函数就是一个“模板方法”。
而基本方法又可以分为三种:抽象方法(Abstract Method)、具体方法(Concrete Method)和钩子方法(Hook Method):
抽象方法:一个抽象方法由抽象类声明,由具体子类实现。
具体方法:一个具体方法由抽象类声明并实现,而子类并不实现或置换。
钩子方法:一个钩子方法由抽象类声明并实现,而子类会加以扩展。我们这里的onDraw()函数就是一个钩子方法。
六,外观模式
就是多了层封装,SDK常用到
七,build模式
建造(Builder)模式是一种对象构建的设计模式,它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象。
在没有运用构造模式之前,我们可能会使用构造方法还设置初始化对象时候的参数,但是有了build模式,就可以通过build来进行选择性的传参并实例化对象。例如,Android常用的第三方请求网络库okhttp,
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.build();
OkHttpClient类中该方法如下,
public Builder() {
dispatcher = new Dispatcher();
protocols = DEFAULT_PROTOCOLS;
connectionSpecs = DEFAULT_CONNECTION_SPECS;
proxySelector = ProxySelector.getDefault();
cookieJar = CookieJar.NO_COOKIES;
socketFactory = SocketFactory.getDefault();
hostnameVerifier = OkHostnameVerifier.INSTANCE;
certificatePinner = CertificatePinner.DEFAULT;
proxyAuthenticator = Authenticator.NONE;
authenticator = Authenticator.NONE;
connectionPool = new ConnectionPool();
dns = Dns.SYSTEM;
followSslRedirects = true;
followRedirects = true;
retryOnConnectionFailure = true;
connectTimeout = 10_000;
readTimeout = 10_000;
writeTimeout = 10_000;
}
八 ,观察者模式
观察者模式的底层其实是回调,Java中一般可以继承Observable 和Observer来实现被观察者和观察者,在安卓中,更是运用大量的观察者模式,例如,BaseAdapter关联了一个DataSetObservable对象,并实现registerDataSetObserver和unregisterDataSetObserver两个方法实现注册和撤销Observer,方法notifyDataSetChanged间接调用Observer的实现者的onChange()方法,以达到通知数据改变的作用。使用ListView和BaseAdapter组合时,当BaseAdapter的item改变时,我们经常会调用notifyDataSetChanged(),通知Listview刷新。
public abstract class DataSetObserver {
/**
* This method is called when the entire data set has changed,
* most likely through a call to {@link Cursor#requery()} on a {@link Cursor}.
*/
public void onChanged() {
// Do nothing
}
/**
* This method is called when the entire data becomes invalid,
* most likely through a call to {@link Cursor#deactivate()} or {@link Cursor#close()} on a
* {@link Cursor}.
*/
public void onInvalidated() {
// Do nothing
}
}
public abstract class Observable<T> {
/**
* The list of observers. An observer can be in the list at most
* once and will never be null.
*/
protected final ArrayList<T> mObservers = new ArrayList<T>();
/**
* Adds an observer to the list. The observer cannot be null and it must not already
* be registered.
* @param observer the observer to register
* @throws IllegalArgumentException the observer is null
* @throws IllegalStateException the observer is already registered
*/
public void registerObserver(T observer) {
if (observer == null) {
throw new IllegalArgumentException("The observer is null.");
}
synchronized(mObservers) {
if (mObservers.contains(observer)) {
throw new IllegalStateException("Observer " + observer + " is already registered.");
}
mObservers.add(observer);
}
}
/**
* Removes a previously registered observer. The observer must not be null and it
* must already have been registered.
* @param observer the observer to unregister
* @throws IllegalArgumentException the observer is null
* @throws IllegalStateException the observer is not yet registered
*/
public void unregisterObserver(T observer) {
if (observer == null) {
throw new IllegalArgumentException("The observer is null.");
}
synchronized(mObservers) {
int index = mObservers.indexOf(observer);
if (index == -1) {
throw new IllegalStateException("Observer " + observer + " was not registered.");
}
mObservers.remove(index);
}
}
/**
* Remove all registered observers.
*/
public void unregisterAll() {
synchronized(mObservers) {
mObservers.clear();
}
}
}
可以看出,观察者并不一定要继承JDK中的Observable 和Observer。