On Dec 18, 2012, at 1:36 PM, Anne van Kesteren wrote:

> On Tue, Dec 18, 2012 at 6:01 PM, Allen Wirfs-Brock
> <[email protected]> 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.
>> 
>> http://wiki.ecmascript.org/doku.php?id=strawman:object_model_reformation
>> 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
> directly.)

Several, observations

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.

When implementing a URLQuery (or whatever it's called) object in JavaScript you 
might well choose to encapsulate a regular Map object as part of the URLQuery 
internal state.  In that case, you would probably implement the Map interface 
on URLQuery by some sort of wrapper method delegating to the encapsulated Map 
instance.  But the wrapper methods would also do other things, like updating 
the URL string.

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.

Allen
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to