Service Locator)

Source: Internet
Author: User
Document directory
  • Using a segregated interface for the Locator
  • A dynamic service locator
  • Using both a locator and injection with aveon
Using a service locator Use Service Positioner

The key benefit of a dependency injector is that it removes the dependency thatMovieLister

Class has on the concreteMovieFinderImplementation. This allows me to give listers to friends

And for them to plug in a suitable implementation for their own environment. Injection isn' t

The only way to break this dependency, another is to use a service locator.

The main advantage of dependency injection is to eliminate the dependency of movielister on the specific implementation of moviefinder. This allows me to set movielister

Give your friends and let them inject corresponding implementations according to their own environment. Injection is not the only method to remove dependencies. You can also use another method.

Remove the dependency, that is, use the service locator.

The basic idea behind a service locator is to have an object that knows how to get hold

All of the services that an application might need. So a service locator for this application

Wocould have a method that returns a movie finder when one is needed. Of course this just shifts

The burden a tad, we still have to get the locator into the Lister, resulting in the Dependencies

Of figure.

The most basic idea of a service locator is that an object locator knows how to control all services required by an application. So in the above example

A service locator of the mentioned application will use a method to return a movie finder instance as needed. Of course, this is just

We still have to get the service locator into Lister, and the result shows the following dependency.

In this case I'll use the servicelocator as a singleton registry. The Lister can then use that

Get the finder when it's instantiated.

In the following example, I will use a service locator as a single-instance registrar. Movielister can use this service locator to obtain

The instance of moviefinder.

class MovieLister...
    MovieFinder finder = ServiceLocator.movieFinder();
class ServiceLocator...
    public static MovieFinder movieFinder() {
        return soleInstance.movieFinder;
    }
    private static ServiceLocator soleInstance;
    private MovieFinder movieFinder;

As with the injection approach, we have to configure the service locator. Here I'm doing it in code, but it's not hard

 

To use a mechanic that wocould read the appropriate data from a configuration file.

 

Just like the injection method, we must configure the service locator. Below I will use code to complete this function, but it is not difficult to use the mechanism to read the corresponding data from the configuration file.

 

Class tester...

 

Private void configure (){

Servicelocator. Load (New servicelocator (New colonmoviefinder ("movies1.txt ")));

}

 

class ServiceLocator...
 
    public static void load(ServiceLocator arg) {
                
           soleInstance = arg;
          
    }
 
    public ServiceLocator(MovieFinder movieFinder) {
          
           this.movieFinder = movieFinder;  
 
     }

Here's the test code.

 

The following is the test code.

 

Class tester...

 

    public void testSimple() {
 
 
        configure();
 
        MovieLister lister = new MovieLister();
 
 
        Movie[] movies = lister.moviesDirectedBy("Sergio Leone");
 
 
        assertEquals("Once Upon a Time in the West", movies[0].getTitle());
    }
 

I 've often heard the complaint that these kinds of service locators are a bad thing because they Aren' t testable

 

Because you can't substitute implementations for them. Certainly you can design them badly to get into this kind

 

Trouble, but you don't have to. In this case the service locator instance is just a simple data holder. I can easily

 

Create the locator with test implementations of my services.

 

I often hear some complaints about how these service locators are not good because they cannot be tested because they cannot find alternative implementations. Of course, if your design is poor

 

But you can choose a proper design. In this example, the service locator is just such a simple data container, and I can easily use the service test implementation to create my locator.

 

For a more sophisticated locator I can subclass service locator and pass that subclass into the Registry's class variable.

 

I can change the static methods to call a method on the instance rather accessing instance variables directly. I can provide

 

Thread specific locators by Using thread specific storage. All of this can be done without changing clients of service locator.

For a more advanced positioner, I can use a subclass to inherit and pass the subclass to the class variable of the Register (implement a servicelocator subclass and pass it to the class variable at initialization)
Soleinstance ). I can modify the static method to call a method of the servicelocator instance instead of directly accessing the instance variable. (Not direct access
Soleinstance. moviefinder method ). I can also provide thread-related storage mechanisms to provide thread-related locators. All of these do not need to change the client's service locator.
    A way to think of this is that service locator is a registry not a singleton. A singleton provides a simple way of 
implementing a registry, but that implementation decision is easily changed. 
One way to improve is that service locators are still registrars rather than Singleton. Singleton provides a simple way to implement the registration machine, but that implementation is easily changed.
Using a segregated interface for the LocatorIsolate service locators

One of the issues with the simple approach above, is that the movielister is dependent on the full service locator class,

 

Even though it only uses one service. We can reduce this by using a segregated interface. That way, instead of using

 

Full service locator interface, the Lister can declare just the bit of interface it needs.

 

The preceding simple method has a problem: movielister relies entirely on the service locator class, although it only uses a service. We can use isolated interfaces to reduce

 

This dependency. In that case, movielister can just declare the interface it requires, rather than using the entire service locator interface.

 

In this situation the provider of the Lister wocould also provide a locator interface which it needs to get hold of the finder.

 

In this case, the movielister provider will also provide a locator interface, and movielister needs this locator interface to control moviefinder.

 

public interface MovieFinderLocator {
 
    public MovieFinder movieFinder();
 
 

The locator then needs to implement this interface to provide access to a finder.

 

The service locator needs to implement this interface to provide access to moviefinder.

 

MovieFinderLocator locator = ServiceLocator.locator();
(Interfaces used by different service providers are isolated to avoid interface pollution)
 
MovieFinder finder = locator.movieFinder();
 
public static ServiceLocator locator() {
 
        return soleInstance;
 
}
public MovieFinder movieFinder() {
 
        return movieFinder;
}    
private static ServiceLocator soleInstance;    
private MovieFinder movieFinder;
 

You'll notice that since we want to use an interface, we can't just access the services through static methods any

 

More. We have to use the class to get a locator instance and then use that to get what we need.

 

You will find that because we use an interface, we can no longer access the service only through the static method, we must use the class to get a locator instance, let

 

The instance obtains the services we want.

 

A dynamic service locatorDynamic service Positioner 

The above example was static, in that the service locator class has methods for each of the services that you need.

 

This isn't the only way of doing it, you can also make a dynamic service locator that allows you to stash any service

 

You need into it and make your choices at runtime.

 

The above is an example of a static positioner. For every service you need, the service locator class has a corresponding method. This is not the only way to implement the service locator. You also

 

You can use a dynamic positioner, which allows you to register any service you need and decide which service to use at runtime.

 

 

In this case, the service locator uses a map instead of fields for each of the services, and provides generic methods

 

To get and load services.

 

In this example, the service locator uses map to replace each service field and uses a common method to obtain and locate the service.

 

class ServiceLocator...
    
private static ServiceLocator soleInstance;
    
public static void load(ServiceLocator arg) {
        
soleInstance = arg;
    
}
 
    private Map services = new HashMap();
 
    public static Object getService(String key){
 
        return soleInstance.services.get(key);
 
    }
 
    public void loadService (String key, Object service) {
 
        services.put(key, service);
 
    }
Configuring involves loading a service with an appropriate key.

 

You also need to configure the service positioner to load the service object and the appropriate keywords to the positioner.

 

class Tester...
 
    private void configure() {
 
        ServiceLocator locator = new ServiceLocator();
 
        locator.loadService("MovieFinder", new ColonMovieFinder("movies1.txt"));
 
        ServiceLocator.load(locator);
 
    }

I use the service by using the same key string.

 

I use a string with the same name as the service object class as a keyword.

 

class MovieLister...
 
    MovieFinder finder = (MovieFinder) ServiceLocator.getService("MovieFinder");
 

On the whole I dislike this approach. Although it's certainly flexible, it's not very explicit. The only way I can

 

Find out how to reach a service is through textual keys. I prefer explicit methods because it's easier to find where

 

They are by looking at the interface definitions.

 

In general, I don't like this method. Although he is quite flexible, his usage is not clear. I want to locate a service with only keywords in text format.

 

I prefer the intuitive method, because it is easy to locate the service by viewing the interface definition.

 

Using both a locator and injection with aveon

Dependency injection and a service locator aren't necessarily mutually exclusive concepts. A good example of using

 

Both together is the aveon framework. aveon uses a service locator, but uses injection to tell components where

 

To find the locator.

 

Dependency injection and service positioning are not mutually exclusive concepts. A good example of their full use is the avron framework. avron uses a service locator, but it also uses an injection

 

To tell the component how to find the positioner.

 

Berin loritsch sent me this simple version of my running example using aveon.

 

Berin loritsch sent me a simple version of aveon in the previous example.

 
public class MyMovieLister implements MovieLister, Serviceable {    
    private MovieFinder finder;    public void service( ServiceManager manager ) throws ServiceException {
 
        finder = (MovieFinder)manager.lookup("finder");
    }       

The service method is an example of interface injection, allowing the container to inject a service manager into mymovielister.

 

The service manager is an example of a service locator. In this example the lister doesn't store the manager in a field,

 

Instead it immediately uses it to lookup the finder, which it does store.

 

The service method is an example of interface injection. Allowing containers to inject the service manager into mymovielister. The service manager is an example of a service locator. In this example

 

Instead of storing the manager as a field, you can use it to immediately locate moviefinder and store moviefinder as a field.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.