前言
在开发中强调,少用继承,多用组合,在结构型模式中组合模式、装饰者模式、代理模式都能很好避免真实对象或者更好的遵循最小知识原则;
代理或者委托模式是代码隔离非常有效的设计模式;
个人认为代理模式和委托模式没有本质的区别,虽然很多书和Blog区分两中设计模式,但是这两种设计模式都是为其他对象提供代理服务,利用新的对象来对真实对象的属性或者方法实现隔离,防止外部直接访问真实对象;
或者将真实对象的功能实现交由代理对象来实现,可以通过改变不同的代理对象来做到相同的接口有不同的功能实现,并且将复杂的逻辑从真实对象类中分离出去;
其实从下面例子中可以发现,委托的例子只是在代理对象中多了真实对象的转换而已,其实本质没有变化;
Java或者Android系统中的代理或者委托应用
系统中使用动态代理非常多,但是静态代理很少;
Retrofit利用动态代理创建Service
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override public @Nullable Object invoke(Object proxy, Method method,
@Nullable Object[] args) throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
类加载器的双亲委托
可以看Java ClassLoader类加载机制(二)类加载器
Android的AppCompatActivity
AppCompatActivity中所有Activity相关的操作都交给了AppCompatDelegate;
public class AppCompatActivity extends FragmentActivity implements AppCompatCallback,
TaskStackBuilder.SupportParentable, ActionBarDrawerToggle.DelegateProvider {
private AppCompatDelegate mDelegate;
private Resources mResources;
public AppCompatActivity() {
super();
}
@ContentView
public AppCompatActivity(@LayoutRes int contentLayoutId) {
super(contentLayoutId);
}
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(newBase);
getDelegate().attachBaseContext(newBase);
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
final AppCompatDelegate delegate = getDelegate();
delegate.installViewFactory();
delegate.onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
}
@Override
public void setTheme(@StyleRes final int resId) {
super.setTheme(resId);
getDelegate().setTheme(resId);
}
...
}
静态代理模式的例子
//制定接口
public interface Image {
void display();
}
//真实执行者
public class RealImage implements Image {
private String fileName;
public RealImage(String fileName){
this.fileName = fileName;
loadFromDisk(fileName);
}
@Override
public void display() {
System.out.println("Displaying " + fileName);
}
private void loadFromDisk(String fileName){
System.out.println("Loading " + fileName);
}
}
//代理对象
public class ProxyImage implements Image{
private RealImage realImage;
private String fileName;
public ProxyImage(String fileName){
this.fileName = fileName;
}
@Override
public void display() {
if(realImage == null){
realImage = new RealImage(fileName);
}
realImage.display();
}
}
//使用
public class ProxyPatternDemo {
public static void main(String[] args) {
Image image = new ProxyImage("test_10mb.jpg");
// 图像将从磁盘加载
image.display(); //Loading test_10mb.jpg Displaying test_10mb.jpg
// 图像不需要从磁盘加载
image.display(); //Displaying test_10mb.jpg
}
}
委托模式的例子
interface I {
void f();
void g();
}
class A implements I {
public void f() { System.out.println("A: doing f()"); }
public void g() { System.out.println("A: doing g()"); }
}
class B implements I {
public void f() { System.out.println("B: doing f()"); }
public void g() { System.out.println("B: doing g()"); }
}
class C implements I {
// delegation
I i = new A();
public void f() { i.f(); }
public void g() { i.g(); }
// normal attributes
public void toA() { i = new A(); }
public void toB() { i = new B(); }
}
public class Main {
public static void main(String[] args) {
C c = new C();
c.f(); // output: A: doing f()
c.g(); // output: A: doing g()
c.toB();
c.f(); // output: B: doing f()
c.g(); // output: B: doing g()
}
}
网友评论