How to design a suitable interface (1)
[Author: Li Wei Add Time: 2001-9-3 8:06:50]
Author: Li Wei, Beijing-Albert software company co-product technical manager
Source: www.cn.ibm.com
Summary: When we design the system interface, we often encounter such problems:
How much method should our interface to provide?
What should our interface provide "atomic approach" or "composite method"?
Is our interface to encapsulate (or, can you package) all details?
The interface design needs to consider the user's usage habits, the convenience of use, the safe use of the safety, according to my programming experience, the following will discuss the two need to weigh the interface designed to weigh the weighted & composite.
interface
The interface provides definition between different systems or between different components of the system. In the software, the interface provides a barrier to separate the target from the implementation, separating the abstraction from the specifically, separating the user from the author.
Standing at the user's point of view, an interface is established and named a method of use of a target object. Some constraints (eg, type systems, time-translational type systems, running exception mechanisms and return values) make the objectives of classists to reflect and strengthen. Affordances refer to the perceived real properties of the refers, these attributes can determine the possible methods of things that provide a clue that operates.
One responsibility for class designers is to reduce the separation, matching targets, and to some degrees of freedom between the interfaces in the interface, and minimize the possibility of using the target object as much as possible.
Encapsulate
For packages, far more than data is private. In the design, the package tend to involve self-containing. If a class requires you know how to call it method (EG in a thread environment, call another method after a method call, you must explicitly synchronize the object), then its encapsulation is better to include all of these and Hidden classes (EG this class is Thread-Safe). The previous design has a design vulnerability, and many of its limited conditions are blurred, and some responsibility is pushed to the user, rather than letting the provider do these work to complete the design.
Performance in space or time (eg, thread, remote method call, message queue), can have a profound impact on the correctness and efficiency of the design. The result of this separation is not ignored:
Concurrently introduced the overhead of the Uncertainty and Context.
The distribution introduced the turnover of the callback, which may be increasing, and will result in errors.
These are designed questions, modifying them, not as simple as modifying bugs.
If an interface is mainly composed of an access method (SET and GET method), each method directly points to a private domain, then its encapsulation will be poor. The domain storage method in the interface usually does not provide information: they cannot communicate, simplify and abstract in the use of objects, which usually causes the code to be lengthy and is easily erroneous.
Therefore, we first consider the first principle of interface design:
Command and Query Second (Command-Query Second)
Requirements: Ensure that a method is not a command (command) is a query (Query)
definition:
Query: When a method returns a value to respond to a problem, it has the nature of the query;
Command: When a method is to change the status of the object, it has the nature of the command; usually, one method may be a pure Command mode or a pure query mode, or a mixture of both. When designing an interface, if it is possible, you should make the interface to be monitored. To ensure that the behavior of the method is command or query, so that the query method does not change the status of the object, there is no side effects, but change the status of the object The method cannot be returned. That is to say: If we want to ask a question, then it should not affect its answer. Actual application, it is necessary to trade off between the specific conditions, the clarity of semantics and the simplicity of use.
For example, in Java.util.ITeratorator, HasNext can be seen as a query, Remove is a command, NEXT merges commands and queries:
Public interface itrator {
Boolean hasnext ();
Object next ();
Void remove ();
}
Here, if you don't put the current value of an Iterator object to the next, you cannot query an Iterator object. If there is no composite method next, we will need to define a series of command methods, such as initialization, continuing, access (Access), and Advance, although they clearly define each action, but The customer code is too complicated:
For (Initialization; Advance) {
... Access for USE ...
}
Command and query functions into a method, which makes it easy for customers, but reduces clarity, and may not be in an assertion-based programming and require a variable to save query results:
Iterator itrator = collection.iterator ();
While (item.hasnext ();) {
Object current = item.next ();
... USE CURRENT ...
}
Below, we consider the second principle of interface design:
Combined method (Combined Method)
The combination method is often used in a thread and distribution environment to ensure correctness and improve efficiency.
Some interfaces provide a large number of methods. At first, these methods appear to minimize, and the relevance is strong. However, in the process of use, some interfaces appear too primitive, which is too simple to force the user to achieve a normal task with more work, and the order and dependence of the method are stronger (ie Temporary coupling). This causes the code to repeat, and it is very troublesome and easy to make mistakes.
Some ways to perform success simultaneously, in the case of multi-thread, abnormal, and distribution, will encounter trouble. If the two actions need to be executed simultaneously, they are described by two separate methods, which must be completely successful, otherwise it will cause rollback of all the actions.
The introduction of threads greatly increases this uncertainty. A series of methods simultaneously call a variable object, if this object is shared between the thread, even if we assume a separate method is thread security, it is not possible to ensure that the result is unexpected. Look at the interface to Event Source, it allows the handle and the query to the event: interface eventsource {
Handler getHandler (Event Event);
Void InstallHandler (Event Event, Handler NewHandler);
}
Cross calls between threads may cause unexpected results. Suppose the Source domain references a thread shared object, the object is likely to be installed a new handle between 1, 2 by another thread:
Class EventsourceExample {
Public void example (Event evenet, handler newhandler) {
OldHandler = eventsource.getHandler (Event); // 1
// The object is likely to be installed a new handle by another thread here.
Eventsource.installHandler (Event, NewHandler); // 2
}
PRIVATE Eventsource Eventsource;
Private Handler Oldrandler;
}