Stripping back objects

R

Roedy Green

I would like to export objects to another machine. The target has no
business knowing all the methods I used to create the objects.

I want to give him just the bare bones data.

Fine, so I build two classes, the core and the goodies. How do you
strip them back down just prior to export serialisation? Is there any
other way other than a field-by-field copy?
 
F

Filip Larsen

Roedy Green wrote
I would like to export objects to another machine. The target has no
business knowing all the methods I used to create the objects.

I want to give him just the bare bones data.

In distributed applications I often make a pretty clean separation between
entity (or data carrying) objects that gets transported or stored and
process (or behaviour defining) objects that pretty much stay in the same
JVM. An entity objects can simply be a Java bean (with only properties) or,
if it makes sense in the context, even just an object with a bunch of public
fields.

Of course, this requires the API to be designed with distribution in mind.
If distribution is to be retrofit to an existing API, then this may not be a
feasible way.

Fine, so I build two classes, the core and the goodies. How do you
strip them back down just prior to export serialisation? Is there any
other way other than a field-by-field copy?

I think that in principle some code somewhere must make a field-by-field
copy for you. If you don't want to write explicit copy/conversion code for
each pair to call from readResolve/writeResolve, you could write a converter
using reflection. If you have an interface defining the core part (using,
say, Java Bean patterns), you could probably even auto-create the core
object as a Proxy object with an underlying Map to carry the actual data.
Hmm, now, why didn't I think of that earlier ...


Regards,
 
R

Roedy Green

I think that in principle some code somewhere must make a field-by-field
copy for you. If you don't want to write explicit copy/conversion code for
each pair to call from readResolve/writeResolve, you could write a converter
using reflection. If you have an interface defining the core part (using,
say, Java Bean patterns), you could probably even auto-create the core
object as a Proxy object with an underlying Map to carry the actual data.
Hmm, now, why didn't I think of that earlier ...

I did it with explicit copies. It was not that many fields. But I
discovered something annoying about java in process.

The thing I want to distribute has a
MiniA object with a MiniB reference.

The thing I want to work with has an
A object with a B reference.

A is a subclass of MiniA and B is a subclass of MiniB.


To strip an A object for export I must create a new MiniA object with
just the fields it needs with a reference to MiniB object with just
the fields it needs.

OK, fine, so there is no simple way to turn a A back to a MiniA.

But I have to declare the reference inside MiniA to MiniB as type
MiniB.

Then A inherits that. It inherits a MiniB reference. It wants a B
reference!!

Obviously, I can store B references in the MiniB variable, but every
time I fish them out of an A object I have to cast them back to type
B.

It seems to me, it should be somehow possible to add EXTRA restriction
on what a field can be in a subclassed object.

In a similar way, when I override a method, the return type should be
permitted to be more restrictive than the type returned in the base
class.
 
F

Filip Larsen

Roedy Green wrote
Obviously, I can store B references in the MiniB variable, but every
time I fish them out of an A object I have to cast them back to type
B.

You could make a method on A that do the typecast for you. That method could
even do lazy conversion of MiniB to B if necessary. Something like

class MiniA {
public MiniB getMiniB() ...
public void setMiniB(MiniB b) ...
}

class A extends MiniA {
public B getB() {
if (!(getMiniB() instanceof B)) {
setMiniB(new B(getMiniB());
}
return (B) getMiniB();
}

public void doSomeWorkOnB() {
getB().doThisBThing();
getB().doThatBThing();
}
}

where I assume there is a B constructor taking a MiniB (and handling nulls
if relevant).



Regards,
 
R

Roedy Green

where I assume there is a B constructor taking a MiniB (and handling nulls
if relevant).

The key is MiniA and MiniB must have NO references of any kind to B.
Otherwise you have to distribute class B (and possibly everything it
is tied to), to the client who is only interested in MiniBs.

So long as any casting method in part of class A, you should be ok.

It still seems odd that you can't put a restriction on the reference
to MiniB in class A, to refine it to a B. There is no way an invalid
reference could sneak in, and the B references are all fine when class
A is used as a MiniA.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,677
Members
48,796
Latest member
Greg L.

Latest Threads

Top