Using a combination of design patterns - chasing girls use a remote proxy mode

This is the third in a series of design patterns, series article directories as follows:

  1. Sentence summary of achieving the same design patterns: Factory mode =? Strategy Mode =? Template Method pattern

  2. Using a combination of design patterns - the decorator pattern beauty camera

  3. Using a combination of design patterns - chasing girls use a remote proxy mode

Previous spoke design patterns using a combination of: the decorator pattern. It is a type of reuse through inheritance, by a combination of multiplexing of behavior, and ultimately to extend the class functionality.

This is an agency model also uses a combination of methods to achieve, and it is very much like the decorator pattern, relatively subtle differences between them are very interesting.

Why should the agent?

Acting is to help you do things the object, why entrust it to help you do? Because it is too complicated to do, there is something you need to know the details, so it will be entrusted to a special object to handle.

Like visa agent in real life, countries do need a visa to the materials and processes vary, and some complex. So delegated to understand all the details visa agent to help us deal with (after all, there is a big push bug waiting for us).

In actual programming, complex things may have so few: Remote Object Access (remote agent), create expensive objects (virtual proxy), expensive objects cache (caching proxy), restrict access to an object (protection agent), and so on.

Local & Remote

java, remote and local standards division is: "Do they run in the same memory heap" .

  • Application on one computer application to call another computer over a network is called remote method invocation, because the heap memory to run two applications on different computers.
  • Android system, each application running in each process, each process has a separate virtual machine, so they run on the same computer memory heap of different calls cross-process is also known as remote call.

Remote & remote agent call

Long-distance call than a local call complicated because of the need for local and remote process communication (network or cross-process call).

In fact, the initiator of the call is not necessary to understand these details, it is best simply to initiate calls and get the desired results. So these complicated things to do proxy. (Of course, you can initiate a call to the business logic details and remote call initiated write together, process-oriented code is to do so)

Take the cross-process communication Android as an example: initiate an application called server application called a client, response to the call of the call. Service definition interface in the form of a suffix aidlof the file:

//以下是IMessage.aidl文件的内容
package test.taylor.com.taylorcode;
interface IMessage {
    //系统自己生成的接口
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,double aDouble, String aString);
    //这是我们定义的服务接口
    int getMessageType(int index) ;
}
复制代码

The system will automatically IMessage.aidlgenerate the corresponding document IMessage.javafile:

public interface IMessage extends android.os.IInterface {
    //桩
    public static abstract class Stub extends android.os.Binder implements test.taylor.com.taylorcode.IMessage {
        public Stub() {
            this.attachInterface(this, DESCRIPTOR);
        }

        //客户端调用这个接口获取服务
        public static test.taylor.com.taylorcode.IMessage asInterface(android.os.IBinder obj) {
            //创建代理对象(注入远程对象obj)
            return new test.taylor.com.taylorcode.IMessage.Stub.Proxy(obj);
        }
        
        //代理
        private static class Proxy implements test.taylor.com.taylorcode.IMessage {
            //通过组合持有远程对象
            private android.os.IBinder mRemote;
            //注入远程对象
            Proxy(android.os.IBinder remote) {
                mRemote = remote;
            }
            
            //代理对象对服务接口的实现
            @Override
            public int getMessageType(int index) throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                int _result;
                try {
                    //包装调用参数
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeInt(index);
                    //发起远程调用(通过一些natvie层方法最终会调用服务端实现的stub中的方法)
                    mRemote.transact(Stub.TRANSACTION_getMessageType, _data, _reply, 0);
                    _reply.readException();
                    _result = _reply.readInt();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }
        }
    }
}
复制代码

(Agent for focusing on this concept, a large number of irrelevant detail code is omitted.)

The system automatically generates two key inter-process communication classes: Stub桩and Proxy代理. They are inter-process communication concept Android in pairs. Is a service-side implementation of the service interface, 代理the client agent for the pile. fainted. . Why so much out to the whole concept, get so complicated?

In fact, in order to simplify the code cross-process communication, the details of the package cross-process communication in the proxy, the client can call a method of the proxy class (proxy and client are in the same memory heap, it is also known 远程的本地代理), initiated by the inter-agency process calls and returns the results to the client. Agent plays shield complex inter-process communication details of the role, so that the client thought he was directly call the remote method.

Pile and agents have the same type, they implement the service interface IMessage, but the pile is abstract and concrete implementation will be placed on the server. The server usually achieve the pile in the Android system components Service:

public class RemoteServer extends Service {
    public static final int MESSAGE_TYPE_TEXT = 1;
    public static final int MESSAGE_TYPE_SOUND = 2;
    
    //实现桩
    private IMessage.Stub binder = new IMessage.Stub() {
        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {}

        //定义服务内容
        @Override
        public int getMessageType(int index) throws RemoteException {
            return index % 2 == 0 ? MESSAGE_TYPE_SOUND : MESSAGE_TYPE_TEXT;
        }
    };

    //将服务实例返回给客户端
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }
}
复制代码

Client to obtain service instances by binding service:

IMessage iMessage;
Intent intent = new Intent(this, RemoteServer.class);
ServiceConnection serviceConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        //将服务实例(桩)传递给asInterface(),该方法会创建本地代理并将桩注入
        iMessage = IMessage.Stub.asInterface(iBinder);
    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {
        iMessage = null;
    }
};
//绑定服务
this.bindService(intent, serviceConnection, BIND_AUTO_CREATE);
复制代码

After successful binding service, onServiceConnected()it will be called back, the local agent will be created, then the client can iMessage.getMessageType()request a remote service.

Remote proxy mode vs decorator pattern

Remote Agent and use the decorator pattern to achieve exactly the same way, they both describe together will seem very interesting:

  • Decorator and the decorator of the same type, by a combination of holding the decorator decorator
  • Agents and the agents have the same type, the agent being held by a combination of those agents

big head. . . Now why should the same area is divided into two modes? But if they are combined with the intention to compare subtle differences can be found:

  • The decorator pattern through inheritance + in combination, on the basis of the original multiplex type and behavior on their extensions .
  • Remote Agent mode by way of inheritance + combination, to achieve the proxy object access control .

If you insist on using the decorator pattern of lines to describe the agency model is also nothing to it: "Acting is decorated by the broker, its extension so that it can be accessed by a remote object." This sentence is completely plausible, but a little strange.

If you try to add a little anthropomorphic color, remote proxy mode and the decorator pattern becomes fine distinction!

  • Use proxy mode as if to say: "I love you, but I can not reach you so I need a proxy (may be your girlfriends).".
  • Use the decorator pattern as if to say: "I love you and another person of the same type so I need you to decorate it.." (Well, you can not find a girlfriend)

Follow-up

We intend to use this 1article to summarize those that use a combination of design patterns, including the Decorator Pattern, proxy mode, the adapter mode, aspect mode and state mode.

Chien did not expect to read, read, becomes a nchapter. . . .

Never imagined that a proxy mode read, read, discovered that if all the scenarios finish, space would be too long, desperation only in this blank. In particular multi-agency model variant, there are subtle differences between them on the implementation and the intent to be analyzed next time.

Guess you like

Origin blog.csdn.net/weixin_33725515/article/details/91399805