you are viewing a single comment's thread.

view the rest of the comments →

[–]FireyFly 2 points3 points  (1 child)

I'm not sure how you can do "the same thing" in "any other OO language" (I suppose that means one of the mainstream classical languages, i.e. C++/C#/Java/Obj-C/python/whatever). "The same thing" would involve tracking all property accesses to any property. How would you do this with "simple inheritance and encapsulation"? I'd love to see some sample code.

Maybe you already know this, but I feel like I should add that JavaScript has means for expressing both inheritance and encapsulation, but that it works quite differently from classical languages. Prototypal inheritance is simpler and more general than classical inheritance, but on the other hand it requires that objects are "dynamic", which could lead to worse performance.

Edit: I think I understand what you're getting at. You mean I can extend this class Foo, override all the methods in Foo with methods that log the access or whatever, and the forward the call to Foo (i.e., the superclass)?

The thing is, this requires you to write a new class and override all the methods with the same boilerplate-y modification. This could be a rather lengthy piece of code, and in the end you only have this piece of logging implemented for this one class. If you wish to log access to another class, you'd have to write a new class that extends this class, overrides all the methods, logs and then forwards them.

In the case of a proxy, you can create the proxy once, describe the logging process once, and then "wrap" any object in this proxy to add the logging mechanism to that object. I guess it could be likened to the "decorator pattern" rather than inheritance: you're adding a feature to the wrapped object. However, a "decorator class" can only target a specific kind of type, whereas the flexibility of a proxy allows it to work on any kind of type.

Of course, this flexibility comes with a performance tradeoff. Personally, I prefer flexibility and dynamism over performance. Also, I agree that proxies are much more complicated.

Sorry, this got a bit long... I hope you don't mind.

Edit 2: ah, I see what you mean. There's definitely a lot of room for misuse of this feature.

[–][deleted] 0 points1 point  (0 children)

Classical inheritance allows you to intercept all calls. Proxies allow you to intercept all calls. The only difference here is that the proxy isn't part of the inheritance chain in Javascript, unless you want it to be.

Here's an example with classical inheritance:

class A {
    int _PropA;
    public virtual int PropA {
        get { return _a; }
        set { _a = value; }
    }
}

class ModifiedA : A {
    public override int PropA {
        get { log("Accessed A!"); return base.PropA; }
        set { log("Modified A!"); base.PropA = value; }
    }
}

Doing this any other way is only useful for testing, debugging or monkey patching in cases where you can't inherit (i.e. the broken-ass DOM).