5

Let's say you have a Client and a Server that wants to share/synchronize the same Models/Objects. The models point to each other, and you want them to keep pointing at the same object after being sent/serialized between the client and the server. My current solution roughly looks like this:

class Person {
    static Map<Integer,Person> allPeople;
    int myDogId;

    static Person getPerson(int key){
        return allPeople.get(key);
    }

    Dog getMyDog() {
        return Dog.getDog(myDogId);
    }
}

class Dog {
    static Map<Integer,Dog> allDogs;
    int myOwnersId;

    static Dog getDog(int key) {
        return allDogs.get(key);
    }

    Person getMyOwner() {
        return Person.getPerson(myOwnersId);
    }
}

But i'm not too satisfied with this solution, fields being integer and stuff. This should also be a pretty common problem. So what I'm looking for here is a name for this problem, a pattern, common solution or a library/framework.

kornfridge
  • 4,774
  • 6
  • 26
  • 39
  • btw. I found out that there's a name for the `static Map` technique, called [the multiton pattern](http://en.wikipedia.org/wiki/Multiton) – kornfridge Apr 27 '11 at 07:21

3 Answers3

2

There are two issues here.

  • Are you replicating the data in the Client and the Server (if so, why?) or does one, the other, or a database agent hold the Model?
  • How does each agent access (its/the) model?

If the model is only held by one agent (Client, Server, Database), then the other agents need a way to remotely query the model (e.g., object enumerators, getters and setters for various fields) operating on abstract model entities (e.g, model element identifiers, which might be implemented as integers as you have done).

Regardless of who holds the model (one or all), each model can be implemented naturally. THe normal implementation has each object simply refer to other objects using normal object references, as if you had coded this without any thought of sharing between agents, and unlike what you did.

You can associate an objectid with each object, as you have, but your application code doesn't need to use it; it is only necessary when referencing a remote copy of of the model. Whether this objectid is associated with each object as a special field, a hash table, or is computed on the fly is just an implementation detail.

One way to handle this is to compute the objectid on-the-fly. You can do this if there is a canonical spanning tree over the entire model. In this case, the objectid is "just" the path from root of the spanning tree to the location of object. If you don't have a spanning tree or it is too expensive to compute, you can assign objectids as objects are created.

The real problem with a duplicated, distributed model as you have suggested you have, is keeping it up to date with both agents updating it. How do you prevent one from creating an object (an assigning an objectid) at the same time as the other, but the objects being created are different with the same objectid, or the same with with different Objectids? You'll need remote locking and signalling to keep the models in sync (this is the same problem as "cache coherency" for multiple CPUs; just think of each object as acting like a cache line). The way it is generally solved is to designate who holds the master copy (perhaps of the entire model, perhaps of individual objects within the model) and then issue queries, reads, reads-with-intent-to-modify, or writes to ensure that the "unique" entire model gets updated.

Ira Baxter
  • 88,629
  • 18
  • 158
  • 311
0

The only solution I am aware of is to send the complete structure, i.e. Dogs and Persons over the network. Then they will end up pointing to the correct copy on the other side of the network. The implementation of this solution however depends on a lot of circumstances. For example when your inclusion relation defines a tree you can go at this problem differently than if it is a graph with cycles.

Have a look at this for more information.

LiKao
  • 10,010
  • 5
  • 47
  • 85
0

I guess one can use the proxy pattern for this.

Sujay Ghosh
  • 2,670
  • 6
  • 27
  • 40