This goes to some basic principles of object design. When you add state members to an object you should think about the life cycle of the member. I try to follow three basic rules:
1) Favor immutability. I.E. - set state upon initialization and don't allow
it to change. No setters or other mutators (and make the object 'final').
Immutable objects are gold for optimizing for speed and memory efficiency.
2) Use accessor methods. Even for internal access to a member field, use a
getter method. This allows you to optimize access to the member or to use
lazy initialization when appropriate. Let the compiler and runtime optimize
the method access away. You are kidding yourself if you think it is faster
to directly access a member field. This is not C.
3) If an object is to have mutable state, all mutation of a member should be
through a single point - a setter or a specific mutator. Do not ever assign
the value of the member directly. This allows you to implement any caching
or optimizations in one place.
So per your question below, so long as all attributes are properly wrapped
in getter/setters, then the act of pulling their values out of the
underlying dictionary stream and storing them in instance fields is simply
done within the accessors. If you mutate a field, the setter updates the
dictionary AND the member field. Per Jukka's comments, that implementation
detail is completely hidden behind the getter/setter abstractions. Example:
private PDPage page;
public PDPage getPage(){
if(page==null){
page = getCOSDictionary().get(PAGE);
}
return page;
}
public void setPage(PDPage page){
this.page = page;
getCOSDictionary().put(PAGE,page);
}
If an object is Serializable, one further consideration is whether a member
field is derivable from other state information. If so, you should mark the
field *transient* and lazily derive it in the getter.
-----Original Message-----
From: Johannes Koch [mailto:[email protected]]
Sent: Wednesday, January 20, 2010 5:24 AM
To: [email protected]
Subject: Re: COSDictionariable?
Hi Jukka
Jukka Zitting schrieb:
> Hi,
>
> On Tue, Jan 19, 2010 at 1:45 PM, Johannes Koch
> <[email protected]> wrote:
>> Jukka Zitting schrieb:
>>> I'm not a big fan of the COSObjectable mechanism as it breaks the
>>> layers of abstraction.
>>>
>>> Is there some other way we could achieve the same functionality?
>> What is the functionality you want to achieve?
>
> I was referring to your request about PDFBox objects giving access to
> the underlying dictionary. Could we rather solve such cases with more
> task-specific methods that wouldn't expose the object internals?
I don't think the COSObjectable interface with its public getCOSObject
is necessary. But I would like to have one object wrapping the
dictionary (giving protected access via getCOSDictionary()), so more
specific PD objects could extend it.
> An example of the problem such direct access causes are the various
> memorized values we've recently added to avoid the performance hit of
> repeatedly looking things up from the underlying directory maps. The
> correctness of such code depends on the dictionary not being modified
> by external code.
Do you mean more specific PD objects should have member properties for
faster access to the values instead of recreating them with each access?
E.g. PDStructureElement would get
private PDPage page;
for faster access, initialized with a PDPage object created from the
"Pg" entry in the dictionary. Of course, this PDPage object has to be
updated if the underlying dictionary entry changes. How?
--
Johannes Koch
Fraunhofer Institute for Applied Information Technology FIT
Web Compliance Center
Schloss Birlinghoven, D-53757 Sankt Augustin, Germany
Phone: +49-2241-142628 Fax: +49-2241-142065
smime.p7s
Description: S/MIME cryptographic signature
