Announcement Announcement Module
Collapse
No announcement yet.
AOP and pattern design Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • AOP and pattern design

    Currently I'm doing some basic reading about the "extension object" pattern.

    This pattern involves a lot of technical stuff like castings from A to B, asking for extensions....

    Proposal: Instead of doing all this manually, it may be done through AOP. Now, the task is to translate this concern into an AOP aspect.

    Problem: I have no pratical AOP experience.

    Can someone help me to understand how this pattern may be translated to AOP.



    Extension object:

    A concrete base class, Subject, provides mechanisms to dynamically
    add and query for extensions. A given extension must be
    downcast to its specific interface (SpecificExtension) for use. The
    pattern as a whole amounts to defining a standard way to cross
    cast from one interface reference to another.

    The aspect-oriented alternative to extension objects is extension
    aspects (Figure eight). This approach eliminates the need for client
    cross casting from one extension (or base interface) to another by
    directly injecting the implementation of a specific interface into a
    class seen by a given set of clients. Besides removing the cross
    casting from client code, this approach reduces the run-time
    overhead of the cross cast and the design complexity as measured
    in number of classes and methods. The core functionality is more
    reusable since its extension mechanism is not predefined via
    inheritance from Subject and dependence upon Extension.
    Excerpt taken from
    http://www.cs.ubc.ca/~kdvolder/Works...2-nordberg.pdf

    Page 3/6


    Thank you.

  • #2
    Though I'm not a Spring expert and have only begun to use AOP via Spring, it seems the "Extension Pattern" (after a very quick look) is used all over the place in Spring.

    The reference manual has good stuff to get you started:
    http://www.springframework.org/docs/reference/aop.html

    BTW, here is another AOP Pattern reference: http://www.cs.ubc.ca/~jan/AODPs/


    --- Josef Betancourt

    Comment


    • #3
      Code:
      String clazz = "com.moo.foo.bar"
      AdapterA adaptA = SomeFactory.newInstance(AdapterA.class, clazz);
      AdapterB adaptB = SomeFactory.newInstance(AdapterB.class, clazz);
      Now consider the above code:

      Suppose class "com.moo.foo.bar" implements two interfaces AdapterA and AdapterB and SomeFactory is a static Factory, trying to fullfill our expectations, which are:

      1. SomeFactory has a build-in classloader that loads the specified class at runtime. (Assuming it to be in our classpath)

      2. We want SomeFactory to create our Adapter objects without having to class cast manually.

      3. The only information we want to pass, is the class name and the type of interface we expect.

      4. SomeFactory should have only one newInstance method for any case, so we can add new interfaces easily, if our requirements have changed, without having to add a new newInstance for each type:

      Code:
      static Object newInstance(Class c, String clazz)
      Can (Spring) AOP turn a generic return type like for instance "Object" into the demanded type at runtime?.


      <dream>
      The next enhancement could be:
      Code:
      String clazz = "com.moo.foo.bar"
      AdapterA adaptA = SomeFactory.newInstance&#40;clazz&#41;;
      AdapterB adaptB = SomeFactory.newInstance&#40;clazz&#41;;
      Let AOP look at the demanded return type and it will cast dynamically from Object to AdapterA or AdapterB
      </dream>

      Comment


      • #4
        Would Spring's BeanFactory be able to fulfill bullet point three?

        Code:
        Object getBean&#40;String,Class&#41;&#58; returns a bean, registered under the given name. The bean returned will be cast to the given Class. If the bean could not be cast, corresponding exceptions will be thrown &#40;BeanNotOfRequiredTypeException&#41;. Furthermore, all rules of the getBean&#40;String&#41; method apply &#40;see above&#41;
        It seems that it could. But this is not really AOP just an example of a Factory pattern. But, I'll step aside and let the experts answer.

        Comment


        • #5
          Originally posted by jbetancourt
          Would Spring's BeanFactory be able to fulfill bullet point three?

          Code:
          Object getBean&#40;String,Class&#41;&#58; returns a bean, registered under the given name. The bean returned will be cast to the given Class. If the bean could not be cast, corresponding exceptions will be thrown &#40;BeanNotOfRequiredTypeException&#41;. Furthermore, all rules of the getBean&#40;String&#41; method apply &#40;see above&#41;
          It seems that it could. But this is not really AOP just an example of a Factory pattern. But, I'll step aside and let the experts answer.
          Thank you for posting the links, they are very helpfull!

          It could, if your world remains static every single day 7/7 * 53


          Object getBean(String,Class): returns a bean, registered under the given name
          but problem is the highlighted word "registered". So we are not talking about runtime conditions.

          *And* we are completly circumventing Spring Factories, because SomeFactory uses a selfmade classloader.

          Comment


          • #6
            Why wrong with doing this?

            Code:
            AdapterA adaptA = &#40;AdapterA&#41; SomeFactory.newInstance&#40;AdapterA.class, clazz&#41;;
            As Java is strongly typed there's no way to avoid the cast.

            Comment


            • #7
              Originally posted by oliverhutchison
              Why wrong with doing this?

              Code:
              AdapterA adaptA = &#40;AdapterA&#41; SomeFactory.newInstance&#40;AdapterA.class, clazz&#41;;
              As Java is strongly typed there's no way to avoid the cast.
              No I don't want to avoid casts. I do want to understand how AOP can help to build the "extension object" pattern and do the technical concerns for me. Maybe you are correct and this misuses AOP. But first I want to understand if it can be done, then I decide if I use it

              Comment


              • #8
                From figure 8:
                An aspect-oriented extension to an existing class simply augments that class to directly or indirectly realize the desired specific interface, eliminating the run-time crosscasting mechanism of the Extension Object pattern.
                You can introduce interfaces to classes (Ref. Manual Section 5.3.2.5. Introduction advice).

                Comment


                • #9
                  The DelegatingIntroductionInterceptor is designed to delegate an introduction to an actual implementation of the introduced interface(s), concealing the use of interception to do so. The delegate can be set to any object using a constructor argument; the default delegate (when the no-arg constructor is used) is this. Thus in the example below, the delegate is the LockMixin subclass of DelegatingIntroductionInterceptor. Given a delegate (by default itself) a DelegatingIntroductionInterceptor instance looks for all interfaces implemented by the delegate (other than IntroductionInterceptor), and will support introductions against any of them
                  Now this is quite difficult to understand!

                  Let's start with the first sentence

                  The DelegatingIntroductionInterceptor is designed to delegate an introduction to an actual implementation of the introduced interface(s), concealing the use of interception to do so.
                  Ok, the situation is, I'm loading a class via Class.forName() from whom I know that it implements one or more given interfaces.
                  You may describe it as
                  <T> object = <T> Class.forName("com.moo.bar")
                  where T is either InterfaceA, InterfaceB,...

                  So, at this moment I'm not interested in introducing an interface, because I already know what interfaces the loaded object implements. I'm only looking for a possibility to advice the above expression to dynamically replace parameter <T> depending on which interface is requested.

                  The next step could be to introduce new interfaces paired with new behaviour, to extend the object's capabilties. But I was glad, if could understand only the first part.

                  Comment


                  • #10
                    Code:
                    <T> object = <T> Class.forName&#40;"com.moo.bar"&#41;
                    This makes no sence. The only types you can cast Class to are Class and Object. Do you mean?

                    Code:
                    <T> object = <T> Class.forName&#40;"com.moo.bar"&#41;.newInstance&#40;&#41;

                    So, at this moment I'm not interested in introducing an interface, because I already know what interfaces the loaded object implements. I'm only looking for a possibility to advice the above expression to dynamically replace parameter <T> depending on which interface is requested.
                    There is no way in Java to dynamically change a cast at runtime. Unless you use code generation or pure reflection you will *always* have to cast to the requied interface at some point. Can you please send through another explanation of what it is you are trying to do. I don't understand your examples so far.

                    Ollie

                    Comment


                    • #11
                      Originally posted by oliverhutchison
                      Do you mean?

                      Code:
                      <T> object = <T> Class.forName&#40;"com.moo.bar"&#41;.newInstance&#40;&#41;
                      You are correct . That's what I meant, sorry.

                      Originally posted by oliverhutchison
                      So, at this moment I'm not interested in introducing an interface, because I already know what interfaces the loaded object implements. I'm only looking for a possibility to advice the above expression to dynamically replace parameter <T> depending on which interface is requested.
                      There is no way in Java to dynamically change a cast at runtime. Unless you use code generation or pure reflection you will *always* have to cast to the requied interface at some point.
                      I know, that`s why I'm looking for an AOP solution.

                      Originally posted by oliverhutchison
                      Can you please send through another explanation of what it is you are trying to do. I don't understand your examples so far.

                      Ollie

                      Thanks! I will try to explain what I`m doing right now.
                      Before I have to apologize for my explanations if they get too verbose.
                      My english could be better, but I try my best.

                      Ok, I`m writing a small plug-in container.

                      The container
                      The plug-in container is a container with little functionality,
                      that might be expanded through a set of plug-ins.
                      So the main purpose of the container is to to manage the lifecycle
                      (start/stop/...) of the plug-ins and to do the nasty classloader
                      mechanics. All this will happen dynamically at runtime and I do this with
                      classworlds, a project at codehaus (http://classworlds.codehaus.org/)

                      Ok, that`s the container.

                      Now the plug-in.
                      Every plug-in consists of one JAR file and some sort of meta information
                      describing the plug-in`s functionality. This meta file is the
                      plug-in`s manifest. You might know this concept from the Eclipse project.

                      Now the plug-in's manifest describes how the plug-in relates to other
                      plug-ins within the container. This relationship is expressed by so called
                      "Extension Points" and "Extensions".

                      Assume you have a plug-in that adds an authorization service to
                      another plug-in that supports authentication.
                      To be able to add something you need an "extension point"
                      that accepts your extension (e.g. the authorization that want to add).

                      The authentication plug-in makes the extension point available to
                      the authorization plug-in that delivers the extension.

                      Back to the sceanrio:
                      At the time the container loads the authentication plug-in, this plug-in
                      might "ask" the engine to look for some other plug-in that has the
                      authorization functionality, i.e. extension. Now the combination of both
                      plug-ins might make up the login service, that will be controlled by
                      a third "login" plug-in.

                      Smallest common divisor
                      To assure a common point where all plug-ins can "meet",
                      all of these plug-ins must at least implement one interface
                      "IPlatformService" that includes two methods:

                      Class[] getExtensionPoints(); // returns all accepted services, i.e. interfaces

                      Class[] getExtensions(); // returns all supported services, i.e. interfaces


                      Now if the authentication plug-in "asks" the container to look out for an
                      authorization plug-in, then all plug-ins within reach of the container are
                      asked via call of "Class[] getExtensions();" whether they support the
                      requested extension for instance "com.moo.foo.auth".
                      The extension must implement this interface of the requesting caller
                      (i.e. its extension point). If they do so they are instanciated and
                      cast to the requested interface.

                      Because all this is done dynamically, the container cannot predict
                      what interface might be requested. It depends on the extension point of
                      the plugin. Therefore you cannot hard code the cast.
                      But the container can use the information retrieved by calls of
                      Class[] getExtensionPoints(); or Class[] getExtensions();.

                      Again, if getExtensionPoints() of some plug-in returns "com.moo.foo.auth"
                      the container asks all plug-ins by calling getExtensions() if they
                      support this interface. The container must than cast the loaded and
                      instanciated suitable object dynamically to the right interface.
                      Though only the information stated in the manifests of the plug-ins or
                      retrieved by getExtensions() must suffice, to accomplish this task.


                      The alternative
                      Of course, the container may pass objects as a mere "Object" to the
                      plug-in, delegating the responsability to cast the object to the plug-in
                      itself, but then the container looses the ability to control the whole
                      process and indeed the problem is moved out of the container but
                      not yet solved:
                      now every plug-in has to impement its own class casting logic.

                      I hope you now understand why I`m asking for this "autocasting"
                      feature.

                      Code:
                      <T> object = <T> Class.forName&#40;"com.moo.bar"&#41;.newInstance&#40;&#41;
                      Maybe Im taking the wrong path and this "problem" is much easier to solve. I`ll will be glad to hear if there is a better solution.

                      Comment


                      • #12
                        I don't think AOP is going to help you here.

                        The way I see it you've got two options:

                        1) define a single method on your plugin that accepts all extentions:

                        Code:
                        public void setExtention&#40;Class extentionType, Object extention&#41;;
                        the problem with this is that your going to have to do casting and type checking in this method.

                        2) define a setter for each of the extentions that your plugin supports and use reflection to set the values:

                        Code:
                        public void setFooExtention&#40;FooExtention foo&#41;;
                        public void setBarExtention&#40;BarExtention bar&#41;;
                        this is a better solution as you don't have to worry about casting or type checking and easy to implement. All the type checking logic will have to be in your container. Have a look at BeanWrapperImpl for an easy way to get/set properties dynamically (this is what Spring uses in the bean factories).

                        Ollie

                        Comment


                        • #13
                          Originally posted by oliverhutchison
                          I don't think AOP is going to help you here.
                          The aspect-oriented alternative to extension objects is extension
                          aspects (Figure eight). This approach eliminates the need for client
                          cross casting from one extension (or base interface) to another by
                          directly injecting the implementation of a specific interface into a
                          class seen by a given set of clients. Besides removing the cross
                          casting from client code, this approach reduces the run-time
                          overhead of the cross cast and the design complexity as measured
                          in number of classes and methods. The core functionality is more
                          reusable since its extension mechanism is not predefined via
                          inheritance from Subject and dependence upon Extension.
                          Because of the quote I still hope AOP can help. Thanks for now, i see this problem is not of general interest. If I found a solution I will post it.

                          Mo

                          Comment

                          Working...
                          X