I've taken a look on article "Can a leopard change its spots" but it does not contain much more information than Ice documentation. What I'm seeking is simplifying client/server update and looking in the forum I'm not alone. For me facets are not very different from servant's implementation point of view. In most cases smooth upgrading from version A to version B means that client or server has to implement both A and B functionality, which can be thrown away after they both become B. It seems that in most cases it's more easily to implement A&B support on client side and it's obvious enough. However if someone has to implement A&B functionality on server side he or she will be interested in reusing existing functionality. As it is said in your documentation “Quite often, the implementation of a version 2 facet in the server can even re-use much of the version 1 functionality, by delegating some version 2 operations to a version 1 implementation.”
Meantime from a practical point of view I see more better way to do vice versa: implement new functionality in version 2 operations and re-use them from version 1 operations. In most cases new functionality is not quite different from previous and it often can survive using sentinel information, like empty string, 0, None, etc. After upgrading all components server implementation of version 1 could be easily dropped. It would be interesting to hear your comments.
Code:
class HelloV2I : virtual public Demo::HelloV2
{
public:
virtual void sayHello(::Ice::Int,
::Ice::Float,
const Ice::Current&) const;
};
typedef ::IceUtil::Handle<HelloV2I> HelloV2IPtr;
class HelloI : virtual public Demo::Hello
{
public:
HelloI(HelloV2IPtr helloIV2) : m_helloIV2(helloIV2) {}
virtual void sayHello(::Ice::Int,
const Ice::Current&) const;
HelloV2IPtr m_helloIV2;
};
void
HelloI::sayHello(::Ice::Int m,
const Ice::Current& current) const
{
m_helloIV2->sayHello(m, 0.f, current);
}
void
HelloV2I::sayHello(::Ice::Int m,
::Ice::Float n,
const Ice::Current& current) const
{
cout << "int " << m << " and float " << n << endl;
}
HelloV2IPtr helloi = new HelloV2I;
adapter->add(helloi, communicator->stringToIdentity("helloV2"));
adapter->add(new HelloI(helloi), communicator->stringToIdentity("hello"));