From: Sandro M. <naa...@gm...> - 2006-02-12 18:08:52
|
On 2/10/06, Tyler Close <ty...@wa...> wrote: > > I've just uploaded a new release of the Waterken Server to SourceForge. > Once again, this release contains some major changes that break > backwards compatibility. I figured since I'd already done it in the > previous release, there was not much cost to doing it again. Needless > to say, I hope to stop doing this; however, I think it was definitely > worth it this time. > > The main change is to the persistence interface. Prompted by Sandro's > last email, and the freedom that comes with being willing to break > backwards compatibility, I tried to design an interface that would make > it less strange to code a mutable object. Would it be possible to get a heads up on something that might change soon, so I can avoid working on the C# version? When I first built the persistence interface, I was expecting that the > common case would be an object containing many mutable variables. In > this case, a persistent data class containing these variables would > need to be defined, and a second class creating the public interface to > that data class would also need to be defined. By making the public > interface class an inner class, the mutable variables in the persistent > data class could be freely read and assigned, without the need to > create getter and setter methods. Since the public interface class is > an inner class, it has access to the private state of the persistent > data class. For the expected common case, this coding style seemed to > impose the least burden on the programmer. Yes, I realized this usage soon after. It seems more natural to me to have the public interface be the outer class, and to define a private inner clas= s with public/internal fields which are thus visible to the outer class; I believe this achieves the same effect. This inner class could be named "Record" or "Data" or some variation thereof to make it's purpose clear: public final class Hello implements java.io.Serializable { private Key scope; private class DataRecord { public String greeting; } public Hello(final String initial) { data =3D new DataRecord(); data.greeting =3D initial; } public String getGreeting() { return ((DataRecord)scope.query()).greeting; } public void setGreeting(final String greeting) { ((DataRecord)scope.update()).greeting =3D greeting; } } } I think it was just the naming that confused me. "Maker" doesn't properly describe what the object is doing. It adequately describes the static "make()" method, but not the fact that it's also a storage container for th= e inner class. I think the above pattern is clearer in this regard. However, looking at our Hello World example and also the other examples > in the Waterken Server release, it appears that having a single mutable > variable of a predefined type is a very common case. For example, the > Hello World code needs a single mutable string. The IOU code needs a > single mutable integer. The yurl.org wiki code needs a single mutable > object. For all these cases, the minimal implementation requires only > definition of a public interface class, since the persistent data is of > a predefined type. In these cases, the Maker coding style is imposing > an unnecessary burden by requiring the coding of a persistent data > class that has only one variable. So to avoid wear and tear on the > programmer, I've created a new persistence interface. Indeed. The less burden to coding smaller objects, the better IMO. :-) The Hello World example with mutable state now looks like: > > public final class > Hello implements java.io.Serializable { > private Var greeting; > > public > Hello(final String initial) { > greeting =3D Persistent.var(initial); > } > > public String > getGreeting() { return (String)greeting.getValue(); } > > public void > setGreeting(final String greeting) { > this.greeting.assign(greeting); > } > } > > This code is now really close to what the programmer would naturally > write if they weren't dealing with a persistent object interface. I am > hoping it will also seem less "strange", and be easier to learn. I look > forward to your thoughts on this new interface. This is certainly clearer. It will become even less verbose with generics (no casts, etc). That also clarifies the purpose of Var, which is something I wondered about. :-) So would you recommend using Var for all a class's variables, or just for small objects? What are the downsides? Sandro |