美文网首页
设计模式 - 代理模式、委托模式

设计模式 - 代理模式、委托模式

作者: 魏树鑫 | 来源:发表于2019-07-23 20:34 被阅读0次

    前言

    在开发中强调,少用继承,多用组合,在结构型模式中组合模式、装饰者模式、代理模式都能很好避免真实对象或者更好的遵循最小知识原则;
    代理或者委托模式是代码隔离非常有效的设计模式;

    个人认为代理模式和委托模式没有本质的区别,虽然很多书和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()
         }
     }
    

    相关文章

      网友评论

          本文标题:设计模式 - 代理模式、委托模式

          本文链接:https://www.haomeiwen.com/subject/kszalctx.html