Our simple example always instantiates a servant of type
PhoneEntryI. In other words, the servant locator implicitly is aware of the type of servant the incoming request is for. This is not a very realistic assumption for most servers because, usually, a server provides access to objects with several different interfaces. This poses a problem for our
locate implementation: somehow, we need to decide inside
locate what type of servant to instantiate. You have several options for solving this problem:
- Use a separate object adapter for each interface type and use a separate servant locator for each object adapter.
This technique works fine, but has the down-side that each object adapter requires a separate transport endpoint, which is wasteful.
Mangle a type identifier into the
namecomponent of the object identity.
This technique uses part of the object identity to denote what type of object to instantiate. For example, in our file system application, we have directory and file objects. By convention, we could prepend a '
d' to the identity of every directory and prepend an '
f' to the identity of every file. The servant locator then can use the first letter of the identity to decide what type of servant to instantiate:
While this works, it is awkward: not only do we need to parse the
namemember to work out what type of object to instantiate, but we also need to modify the implementation of
locatewhenever we add a new type to our application.
categorymember of the object identity to denote the type of servant to instantiate.
This is the recommended approach: for every interface type, we assign a separate identifier as the value of the
categorymember of the object identity. (For example, we can use '
d' for directories and '
f' for files.) Instead of registering a single servant locator, we create two different servant locator implementations, one for directories and one for files, and then register each locator for the appropriate category:
- Yet another option is to use the
categorymember of the object identity, but to use a single default servant locator (that is, a locator for the empty category). With this approach, all invocations go to the single default servant locator, and you can switch on the
categoryvalue inside the implementation of the
locateoperation to determine which type of servant to instantiate. However, this approach is harder to maintain than the previous one; the
categorymember of the Ice object identity exists specifically to support servant locators, so you might as well use it as intended.