Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Serializing objects that are only available through a factory

Reply
Thread Tools

Serializing objects that are only available through a factory

 
 
Hendrik Maryns
Guest
Posts: n/a
 
      12-02-2008
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

I have some classes (wrappers around a string, each with their own
semantics) which can only be created through a factory method, which
ensures that there is always only one object of the given class with the
given name (String). I want to make these classes Serializable. What
is the best way to do this?

Example class:

import java.util.HashMap;
import java.util.Map;
public class FirstOrderVariable {
private static final long serialVersionUID = -6957388990994668892L;
/**
* Factory method to get a variable. If a variable with the given name
already
* exists, it is returned.
*
* @param name
* The name of the variable.
* @return The unique variable with the given name. If the name is not
* effective, a variable with a random name is returned. | if
( name
* != null ) | then result.getName() == name
*/
public static FirstOrderVariable getVariable(final String name) {
FirstOrderVariable result;
if (name == null) {
result = new FirstOrderVariable();
} else {
result = FirstOrderVariable.variables.get(name);
}
if (result == null) {
result = new FirstOrderVariable(name);
FirstOrderVariable.variables.put(name, result);
}
return result;
}
private static Map<String, FirstOrderVariable> variables = new
HashMap<String, FirstOrderVariable>();
private final String name;
private FirstOrderVariable() {
name = "v_" + FirstOrderVariable.getNumber();
}
private static int getNumber() {
return FirstOrderVariable.totalNumber++;
}
private static int totalNumber = 0;
private FirstOrderVariable(final String name) {
this.name = name;
}
}

I know I should introduce the method readObject(ObjectInputStream in),
but I am unsure what to do in there. Add the name - var mapping to the
static map, yes, but what if there already is a variable with that name?
I can’t return another object from readObject.

Of course, if I deserialize a Formula in which the variable is
contained, inside of that formula, there will only be one variable with
the given name, but if I deserialize multiple formulas, even if
originally they had the same variable, I cannot guarantee that they will
use the same variable now, can I? Even when, maybe the variable has
been created in my application already (likely for names like “x” and
“y”), these have to be the same too.

Grateful for suggestions.

H.
- --
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iEYEARECAAYFAkk1LfQACgkQBGFP0CTku6N9AgCfcQldWPfmj0 K4TU17eD0PuXjB
oR0An2DgawVz06c6xu2mPlwy+r2J/32e
=nrpG
-----END PGP SIGNATURE-----
 
Reply With Quote
 
 
 
 
Hendrik Maryns
Guest
Posts: n/a
 
      12-02-2008
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hendrik Maryns schreef:
> Hi,
>
> I have some classes (wrappers around a string, each with their own
> semantics) which can only be created through a factory method, which
> ensures that there is always only one object of the given class with the
> given name (String). I want to make these classes Serializable. What
> is the best way to do this?
>
> Example class:
>
> import java.util.HashMap;
> import java.util.Map;
> public class FirstOrderVariable {
> private static final long serialVersionUID = -6957388990994668892L;
> /**
> * Factory method to get a variable. If a variable with the given name
> already
> * exists, it is returned.
> *
> * @param name
> * The name of the variable.
> * @return The unique variable with the given name. If the name is not
> * effective, a variable with a random name is returned. | if
> ( name
> * != null ) | then result.getName() == name
> */
> public static FirstOrderVariable getVariable(final String name) {
> FirstOrderVariable result;
> if (name == null) {
> result = new FirstOrderVariable();
> } else {
> result = FirstOrderVariable.variables.get(name);
> }
> if (result == null) {
> result = new FirstOrderVariable(name);
> FirstOrderVariable.variables.put(name, result);
> }
> return result;
> }
> private static Map<String, FirstOrderVariable> variables = new
> HashMap<String, FirstOrderVariable>();
> private final String name;
> private FirstOrderVariable() {
> name = "v_" + FirstOrderVariable.getNumber();
> }
> private static int getNumber() {
> return FirstOrderVariable.totalNumber++;
> }
> private static int totalNumber = 0;
> private FirstOrderVariable(final String name) {
> this.name = name;
> }
> }
>
> I know I should introduce the method readObject(ObjectInputStream in),
> but I am unsure what to do in there. Add the name - var mapping to the
> static map, yes, but what if there already is a variable with that name?
> I can’t return another object from readObject.
>
> Of course, if I deserialize a Formula in which the variable is
> contained, inside of that formula, there will only be one variable with
> the given name, but if I deserialize multiple formulas, even if
> originally they had the same variable, I cannot guarantee that they will
> use the same variable now, can I? Even when, maybe the variable has
> been created in my application already (likely for names like “x” and
> “y”), these have to be the same too.


To answer my own question: I found
http://java.sun.com/developer/JDCTec...02/tt0205.html and
consequently added the following method to the above class:

/**
* If there is already a variable with the name of the deserialized
* object, return that variable, otherwise register this variable
* with the class.
*
* @return The variable registered in this class with the name of
* the deserialized variable. May be the deserialized
* variable itself.
* @throws ObjectStreamException
*/
@SuppressWarnings("unused")
private FirstOrderVariable readResolve()
throws ObjectStreamException {
if (!FirstOrderVariable.variables.containsKey(this.na me)) {
FirstOrderVariable.variables.put(this.name, this);
}
return FirstOrderVariable.getVariable(this.name);
}

I think this is the proper solution. Feedback still welcome of course,
and does anyone have a suggestion as to what to put in the comment to
the throws clause?

TIA, H.
- --
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iEYEARECAAYFAkk1NG8ACgkQBGFP0CTku6MRKgCfeJ1GL9YFLj/kKrHpEZ4Sq+ql
piUAoJB5Fo52DfnuRHvYRtciWqGthOR9
=ViOA
-----END PGP SIGNATURE-----
 
Reply With Quote
 
 
 
 
John B. Matthews
Guest
Posts: n/a
 
      12-02-2008
In article <gh3c9f$g8s$>,
Hendrik Maryns <> wrote:

[...]
> To answer my own question: I found
> http://java.sun.com/developer/JDCTec...02/tt0205.html and
> consequently added the following method to the above class:
>

[...]
> private FirstOrderVariable readResolve()

[...]
>
> I think this is the proper solution. Feedback still welcome of course,
> and does anyone have a suggestion as to what to put in the comment to
> the throws clause?

[...]

The article cites Joshua Bloch's item 57 from the first edition of
Effective Java, "Provide a readResolve method when necessary". The
second edition, item 77, adds to that advice, saying one "should use
enum types to enforce instance control invariants wherever possible."

For comparison, I looked at the JScience library, which implements
Serializable for Polynomial Functions of one or more Variable(s). The
authors appear to be planning to use XML to manage variables by name;
sadly, the feature is marked TODO in version 4.3.1.

My proposed exception message: "The variable name <" + this.name + ">
was a complete surprise to me at this point." Cf.:

<http://www.frivolity.com/teatime/Computers/MPW_errors.html>

--
John B. Matthews
trashgod at gmail dot com
http://home.roadrunner.com/~jbmatthews/
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
problem in running a basic code in python 3.3.0 that includes HTML file Satabdi Mukherjee Python 1 04-04-2013 07:48 PM
Abstract factory and Factory pattern C# ASP .Net 4 07-31-2008 03:22 PM
Serializing custom exception through a webmethod call. Matt Bush ASP .Net Web Services 1 11-11-2004 10:54 PM
Serializing custom exception through a webmethod call. Matt ASP .Net Web Services 1 11-07-2004 09:19 AM
Abstract Factory or Factory Method pattern question.... Medi Montaseri C++ 17 09-03-2003 06:50 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57