allen at wirfs-brock.com
Tue Dec 18 18:20:23 PST 2012
On Dec 18, 2012, at 1:36 PM, Anne van Kesteren wrote:
> On Tue, Dec 18, 2012 at 6:01 PM, Allen Wirfs-Brock
> <allen at wirfs-brock.com> wrote:
>>> It seems you either need to use a Proxy, some kind of wrapper method,
>>> or a custom implementation in most cases. Typically when objects akin
>>> to Map or Array are exposed in a platform API, mutating them has
>>> observable (synchronous) side effects.
>> proposes a mechanism that would support defining such object behaviors
>> without requiring the full magic of Proxy.
> I think we're talking past each other or I might be misunderstanding.
> Lets say that hypothetically Map is sufficient for URL query
> parameters and we do not need a MultiMap for its semantics. We have a
> URL object and you can get to its query parameters using
> URL.prototype.query. That property cannot point directly to a Map
> because when I perform an operation on that Map, say
> query.delete("x"), not only should "x" be deleted from the Map, it
> should also be removed from URL's string synchronously. The latter
> does not seem possible using Map directly, but such a pattern is found
> all over.
> (That delete()'s and friends argument needs to be stringified is
> another reason of course that makes it hard to reuse native types
1) yes, we probably are talking past each other, sorry...
2) To me, we are also talking about OO design esthetics and we may well be applying different esthetics.
As you now more fully describe the situations, I would say, that a "query object" certainly should not be just a Map or any other basic collection style object. The reason is that the primary role of any collection is to hold and provide structured access (in some specific manner) to a collection of data. (see http://www.wirfs-brock.com/PDFs/Characterizing%20Classes.pdf ). As soon as you starting adding domain specific semantics to a collection you are giving it a very different role. Probably that of a service provider or coordinator.
In this case, (and without really knowing your actual requirements for a URL query parameter object) I would say the value provided by URL.prototype.query should be an instance of the URLQuery class (or would URLFilter or URLInspector be a better name) whose primary responsibility is to support structured manipulation/inspection of a URL. It may present a Map-like interface for accomplish for performing these manipulations. But that collection style interface is simply a secondary (although perhaps very convenient) characteristic of the object.
3) When initially setting a query on an URL, it may be convenient to pass the parameters for initialize the query object as a regular Map or other generic collection. That's fine, as long as it is understood that what is being passed is only initialization parameters and that the actual query object will be a new object (probably of a different domain specific kind) rather than the Map that was originally passed.
3) I agree, this pattern is found all over and in all kinds of applications. Arguably it is at the essence of what object-oriented design is all about. When do you reuse a canned general purpose object and when do you need to introduce a new application domain specific special-purpose kind of object.
Many years ago I coined a phrase for a style guideline for Smalltalk programmers. It was "never use an Array when an Object will do". The basic idea is still the same, and it really applies to all generic collection objects and all languages. The basic message is don't place application domain specific behavior into general purpose collection objects and conversely don't use a general purpose collection where you need to have domain specific behavior. Use a domain object (eg, URLQuery) in situations like this.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the es-discuss