Re: Replacing 'new'?
- From: Stefan Weiss <krewecherl@xxxxxxxxx>
- Date: Thu, 24 Sep 2009 00:08:44 +0200
On 23/09/09 18:30, Dmitry A. Soshnikov wrote:
On 23 сен, 19:05, Stefan Weiss <krewech...@xxxxxxxxx> wrote:
Now checkSlices() is accessible to any user of my Sandwich. I'd rather
hide it, because I may want to change it later
Yes, sure, but saying that, you again think about encapsulation in
"security" reason, afraid that some can change something that you
don't wanna be changed. If someone wants to change encapsulating data
- he will do it. Just opens your source code and make this method
public. The reason is - user needs it. More than, as you know, such
"encapsulated vars" is not 100% hidden [...]
That's not why I'm hiding the details. I'm not concerned about people
changing or accessing parts of my code against my will. The reason why I
want to keep the hypothetical checkSlices() function from being exposed
as a "public" method is that I need to be able to change its
implementation, or remove it entirely, without worrying about any other
code which may use my object. If they don't see the method, they won't
be tempted to use it, and won't be affected by its change or removal.
and _checkSlices() would still be visible on each sandwich.
Here's a good example how encapsulation is made in Python: there
__private and _protected fields are made by this underscore name
convention and are not accessible from the outside. But from the other
hand, Python just renames such fields to _ClassName__privateField -
and by this name, this property is already accessible from the
outside. The reason? Again, programmer (doesn't matter who - author or
user) wants by himself to get encapsulated data. And if will be some
errors after that - responsible for that is fully programmer, but not
"damn! someone again changed my field :(" or "what a typo!".
I know what you mean, and I agree that concealing one's private parts
isn't that important... ;)
If you assume that whoever uses your objects will be responsible enough
not to rely on fields and methods which have been marked "private" (by
_convention or documentation), there's no harm in making them accessible.
Given the choice, I'd still hide them, because you can present a cleaner
interface to your object. A typical example for a private field would be
a data source (like a database connection object, or an XHR wrapper
object). If the purpose of your object is to present a facade for data
access, the data source will likely be stored as an object property, so
that the facade's methods can access it. From the outside this could
look like:
myObject:
Function loadRecord (loads a record)
Function createRecord (creates a record)
...
Object dataSource (please don't use me)
Responsible users won't call myObject.dataSource.send("raw query")
directly, but IMO the dataSource has no place in myObject's API.
The other benefit of the makeMeASandwich() type of object generation is
that all methods can access the generator function's scope, and can
easily share data without resorting to this._mySharedObject.
And if there's no this *sugar* as private and protected,
keeping in mind that "that's not allowed" and maybe using some naming
conventions as underscore - is quite good encapsulation. At least,
you'll not eat much memory.
I agree, it's good enough. And I'm aware of the memory issue.
Or in your example, just use wrapped context when creating prototype -
in any case checkSlices method is common:
function Sandwich () {
this.upperSlice = Bread.getSlice();
this.lowerSlice = Bread.getSlice();
}
Sandwich.prototype = (function () {
// initialization context
function checkSlices () {
if (this.upperSlice.size != this.lowerSlice.size) {
throw new BreadException();
}
}
function bite () {
checkSlices();
// reduce sandwich size
}
checkSlices();
// prototype:
return {
constructor: Sandwich,
bite: bite
};
})();
var aSandwich = new Sandwich;
That won't work. Look at what |this| in checkSlices refers to.
For example, I would use it to implement a ticker or other widgets, but
I wouldn't use it to model points on a canvas or rows in a table.
Yeah, sure, your choice, i just wanted you to notice main
encapsulation principle, and do not think that if you put something
into private area, everything will be always OK from this moment.
Nope, if user will want to change it - he will - repeat, just will
open your source and change private to public.
That's fine by me. If access to a property is required, it was probably
my mistake not to make it public in the first place.
The sandwich generator isn't the perfect match in every situation, and
it isn't required in any, but in some cases it's a useful pattern.
cheers,
stefan
.
- Follow-Ups:
- Re: Replacing 'new'?
- From: Garrett Smith
- Re: Replacing 'new'?
- From: Dmitry A. Soshnikov
- Re: Replacing 'new'?
- References:
- Replacing 'new'?
- From: optimistx
- Re: Replacing 'new'?
- From: JR
- Re: Replacing 'new'?
- From: Stefan Weiss
- Re: Replacing 'new'?
- From: Dmitry A. Soshnikov
- Re: Replacing 'new'?
- From: Stefan Weiss
- Re: Replacing 'new'?
- From: Dmitry A. Soshnikov
- Re: Replacing 'new'?
- From: Stefan Weiss
- Re: Replacing 'new'?
- From: Dmitry A. Soshnikov
- Replacing 'new'?
- Prev by Date: Re: Number.prototype.toFixed and FAQ
- Next by Date: Re: Session cookie: how to make session cookie written from page in a subdirectory, available to the root directory?
- Previous by thread: Re: Replacing 'new'?
- Next by thread: Re: Replacing 'new'?
- Index(es):
Relevant Pages
|