Constructor-choke variable encapsulation.

I have been chewing over the idea of using constructors which take a single complex object roughly equivalent to a "transfer object" as a means to achieve a sort of flexible encapsulation, and I was wondering whether people would think it is a good idea.

Example.

publicclass Bomb{

privateint clicks;// the number of times the button has to be pushed to get an effect

privateboolean dud;// whether the bomb is a dud or not

public Bomb(int clicks){

this.clicks = clicks;

this.dud =new Random().nextBoolean();

}

publicvoid pushButton(){

clicks = clicks - 1;

if (clicks > 0){

System.out.println("Click.");

}

elseif (dud){

System.out.println("Ffffuuut.");

}

else{

System.out.println("BOOOM!!!!");

}

}

}

The bomb has a button that is pressed using pushButton(). Once the button has been pressed the predetermined number of times, the bomb either blows up or goes "ffffffuuut!!" (turns out to be a dud). Yes, this is a stupid example.

Notice that all the values are encapsulated totally - no getters and no setters. Now say that we decide we want to get to them... sometimes... but not most of the time. For example, we might want to be able to persist the bomb but would prefer not to open it up to do so.

The constructor-choke variable encapsulation idea goes like this.

publicclass BombData{// The equivalent of a DTO

publicint clicks;

publicboolean dud;

}

publicclass Bomb{

private BombData data;

public Bomb(BombData data){

this.data = data;

}

publicvoid pushButton(){

data.clicks = data.clicks - 1;

if (data.clicks > 0){

System.out.println("Click.");

}

elseif (dud){

System.out.println("Ffffuuut.");

}

else{

System.out.println("BOOOM!!!!");

}

}

}

Considered as an instantiated object, the Bomb is no less encapsulated than it was before. There are no methods for accessing or mutating its members. However, the code responsible for instantiating the Bomb can keep a reference to the BombData hanging around for persistence purposes or whatever.

Basically the idea is that the object has a variable level of encapsulation determined by the code which instantiates it. The instantiating code serves a sort of access control role in this purpose, as it can pass references to the BombData to other classes or not, as it pleases.

In our example, in which we want to persist the Bomb, the class responsible for instantiating bombs could be a DAO (which returns actual business object Bombs and NOT BombData transfer objects). All new Bombs must be instantiated using the DAO, which just keeps track of which BombData objects go to which Bombs for when data manipulation requests are made.

Cool idea? Or am I a crackpot? Or is this the so-and-so pattern that I would already have known about if I had read such-and-such a book?

Drake

[5016 byte] By [Drake_Duna] at [2007-10-2 16:19:57]
# 1

I do it all the time.

I do it any time the following happens.

1. The number of parameters is growing and currently exceeds four.

2. The initialization of the parameters varies and default values can be used. For instance if in one case params 1 and 3 need to be set while in another 2 and 4 need to be set.

It is also one of the few times I use inner classes. The definition (the name I use) is defined within the class where it is used. I also usually make the class hold a member to that rather than listing the attributes separately.

jschella at 2007-7-13 17:14:08 > top of Java-index,Other Topics,Patterns & OO Design...
# 2

Thanks for the response, Jschell. I am going to go ahead and use this idea.

Actually, I realized that it provides another advantage as a side effect.

Referring to my Bomb example, say you want it to be nicely encapsulated but you are concerned about extensibility (i.e., if clicks and dud are private members, subclasses of Bomb cannot access them). Well... since the BombData is being passed as a constructor argument, any subclass can grab a reference to it during instantiation and access those members. So it sort of creates the "subclass only" access that I was expressing a wish for in a recent thread.

Drake

Drake_Duna at 2007-7-13 17:14:08 > top of Java-index,Other Topics,Patterns & OO Design...
# 3

Well, I do not have any technical objections to what you have done, mainly philosophical ones. You are separating behavior and logic. The former is your busines object. The latter is your new data object (DTO). IMO, you now have two 'half-objects'. The DTO could easily be called a 'struct' which would more properly connote its role. This kind of separation can be valuable when passing data between tiers (see Command and DTO patterns). However, it does violate encapsulation.

- Saish

Saisha at 2007-7-13 17:14:08 > top of Java-index,Other Topics,Patterns & OO Design...
# 4

> tiers (see Command and DTO patterns). However, it

> does violate encapsulation.

Well yeah, but the point is that I have to persist these bad boys somehow. Isn't this a less egregious violation of the object's encapsulation than adding a whole bunch of get/set methods to it?

Drake

Drake_Duna at 2007-7-13 17:14:08 > top of Java-index,Other Topics,Patterns & OO Design...
# 5

Fair enough. IMO, whenever you move into V/C you start getting constructs lke JavaBeans to bind to a HTML form. Whenever you move towards the persistence tier, you have either structs/DTO's (if using custom persistence) or JavaBeans (if using an O/R mapper). This is okay. Your OO should reside in the domain model. Making compromises on the 'outskirts' where you are forced to deal with other technologies (e.g., HTML or relational).

Take a look at Decorator and Memento as patterns. They may be able to hide some of the persistence details for you.

- Saish

Saisha at 2007-7-13 17:14:08 > top of Java-index,Other Topics,Patterns & OO Design...
# 6

> > tiers (see Command and DTO patterns). However, it

> > does violate encapsulation.

>

>

> Well yeah, but the point is that I have to persist

> these bad boys somehow. Isn't this a less egregious

> violation of the object's encapsulation than adding a

> whole bunch of get/set methods to it?

>

It really involves your overall project and how you do things.

Does this sort of model represent 90% of the objects in your design or 10%?

If it is 90% then you might have a problem.

And how is the passed in DTO used elsewhere? Is it a traditional DTO (like in the java blueprints) or it it used exclusively in interactions with this class?

If it is used exclusively with this class then you could have a problem.

Like I said I do use this form, but excluding traditional DTOs, it seldom shows up in more than three or four classes.

jschella at 2007-7-13 17:14:08 > top of Java-index,Other Topics,Patterns & OO Design...