How to design a suitable interface (2)
[Author: Li Wei Add Time: 2001-9-3 8:06:50]
In order to solve the problem, it is also necessary to complete the user of the class instead of the class:
Class EventsourceExample {
Public void example (Event evenet, handler newhandler) {
Synchronized (Eventsource) {
Oldhandler = eventsource.gethandler (event);
Eventsource.installHandler (Event, NewHandler);
}
}
PRIVATE Eventsource Eventsource;
Private Handler Oldrandler;
}
We assume that the target object EventSource is a remote, and it is very short compared to the time of performing each method body and the delay of communication. In this example, EventSource's approach is called twice and may repeat multiple times in other instances, so that the overhead is also at least twice.
There is also a problem with the use of the external SYNCHRONIZED synchronization block. The reason why the SYNCHRONIZED block will fail, mainly because we work through the agent object, so the caller's SYNCHRONIZED block, synchronized is a proxy object rather than the final target object, the caller cannot do too much. Guarantee.
Combined Method must be implemented simultaneously in the distributed environment, or in the thread environment. It reflects the user's direct application, recovery policies, and some clumsy methods are encapsulated in Combined Method, and simplify the interface, reducing the cumbersome you don't need. The effect of Combined Method is to support a design of a transaction style.
A separate Query method is usually reasonable in a combination of Command-Query. Providing a separate Command method is not common because Combined Method can complete this job, as long as the caller is simple to ignore the return result. If you return a result, you can provide a separate Command method.
Back in the previous example, if the installhandler method returns the handle of the last installed, the design is simpler and independent:
Interface Eventsource {
Handler InstallHandler (Event Event, Handler NewHandler);
}
The customer code is as follows:
Class EventsourceExample {
Public void example (Event evenet, handler newhandler) {
OldHandler = Eventsource.installHandler (Event, NewHandler);
}
PRIVATE Eventsource Eventsource;
Private Handler Oldrandler;
}
In this way, we provide the caller with a safer interface and no longer need them to solve the problem. Thereby reducing risk and code quantity, all the responsibilities of the class design give the class designer rather than the user, even if there is a proxy object, it will not affect the correctness.
A Combined Method can be a collection of query, a collection of Command, or both. In this way, it may supplement the Command, Query method, or may be conflicted with it. When the conflict occurs, the priority choice of Combined Method produces a different correctness and applicability.
In another example, we consider obtaining resources. Suppose, in the interface below, method Acquire is blocked before the resource: interface resource {
Boolean isacquid ();
Void acquire ();
Void release ();
}
Similar to the following code will be recommended in a thread system:
Class resourceexample {
Public void example () {
Boolean acquired = false;
SYNCHRONIZED (Resource) {
IF (! resource.isacquired ())
Resource.acquire ();
Else
acquired = true;
}
IF (! acquired)
...
}
PRIVATE RESOURCE
}
However, even if we give up readability and ease of use, such design is not a COMMAND-Query separation design. If an agent is introduced, it will fail:
Class ActualResource Implements Resource {...}
Class ResourceProxy IMPLEments RESOURCE {...}
If the user can do work through actualResource, you can do work through ResourceProxy, and ActualResource and ResourceProxy have not processed synchronization, the SYNCHRONIZED block may fail. Because, since we can complete the work through the proxy object ResourceProxy, then the caller's SYNCHRONIZED block, the synchronization is the agent object ResourceProxy rather than the final target object ActualResource.
A Combined Method solves this problem, which makes concurrency and indirectness more transparent.
Interface resource {
Boolean tryacquire ();
}
The following code is clear, simple and correct:
Class resourceexample {
Public void example () {
IF (! resource.tryacquire ())
...
}
PRIVATE RESOURCE
}
One result brought by Combined Method is to make some tests and assertion-based programming becomes very awkward, however, it is suitable for solving threads and distribution issues.
In practical applications, the interface should be single or composite, depending on the specific situation.
About author
Li Wei: Beijing Jie He Weiye Software Company Product Technology Department Manager. In 1996, Sichuan University's undergraduate graduated, 5 years of software development experience, mainly engaged in the Internet-based B / S structure Java development, expertise for database, object-oriented technology, etc.