Menu

Design Patterns testing

Developers
deje
2006-07-05
2013-04-19
  • deje

    deje - 2006-07-05

    My idea behind testing design patterns is basically to assert dynamic pattern integrity (as opposed to static structure of the code).
    A few simple ideas were as as follows.
    The singleton:

    <design-pattern>core:singleton</design-pattern>
    <class>MySingle</class>

    this "profile" would be tied to a test method (metaphor). Behind the scenes JO would basically monitor how many times the constructor for MySingle is called and throw an exception if it was more than once. The "core:" prefix represents a namespace or pattern-testing library.

    The profile could be extended too, by providing a getter method that JO could assert will always return the same object.
    I am leaning toward using AspectJ or some AOP framework for the more complex profiling. Although it would be nice to have our own system for managing this.

    Currently these are some of the patterns I am thinking of:

    dependency injection
    singleton
    flyweight
    adapter
    observer-observable
    abstract factory

    Also want to have a system to detect common emerging patterns (like where a pattern SHOULD be used):

    <search-pattern>core:constructor-clutter</search-pattern>
    <package>...

    This will basically search where a constructor can be replaced by a factory method (to decouple implementation decisions).

    Anyway thats the gist of it. feel free to post your thoughts.

     
    • uptown

      uptown - 2006-07-22

      Could you explain a little more about how using Aspect Oriented Programming will fix into creating the more complex profiles.

       
    • deje

      deje - 2006-07-22

      Sure ok. Let's take a step back first:

      To analyze a design pattern at runtime JO has to be constantly aware of each of the objects involved in the pattern. Currently, in the assert tests, this is done by inserting bytecode into appropriate places using javassist.

      This is an easy(-ish) solution if you know exactly what objects and methods you need to monitor (say, for triggers), but becomes harder if this is not easily known--i.e. where do we inject the JO bytecode hooks?

      With aop you can inject bytecode anywhere in very complex ways using queries across a program structure called "pointcuts."

      Let's take the singleton pattern as an example:

      Definition - A singleton has only one (shared) instance in an application.

      We could test this by adding a monitor to each constructor of a class and raise an assert failed if two instances are detected.

      On the other hand if you used a factory method (typical case) it is difficult and awkward to place a monitor IN the factory to determine what it is returning.

      With an an aspect, however, we can weave a pointcut around all CALLS to the factory method (from the "testee") and test that the same shared instance is returned. This gets messy with javassist (need tons of reflection code, careful recompilation checks yada). But the aspect would look like:

      pointcut singleton() : call (com.mydomain.Singleton.getInstance());

      Essentially an AOP framework (even aspectJ) will use a bytecode library like javassist under the hood, but that said, they simplify the work immensely.

      This post is a bit long but I thought it would also serve as documentation for how JO runs tests.

       
    • uptown

      uptown - 2006-08-27

      Since we have decided to go with using AOP (more specifically using the AspectJ libraries), we should pick some patterns to hack out some design on how to test them....

      how about the observer and flyweight from your above mentioned patterns?

       
    • deje

      deje - 2006-09-02

      yea flyweight is a good place to start. A flyweight (from GoF) is basically like a singleton but for instance types.

      The best example is java.lang.Boolean

      Boolean.TRUE is a "singleton" representing state true. similarly FALSE. It is not a straightforward singleton because there are 2 instances of Boolean available in the system.

      For the second I would suggest Multiton over Observer-Observable (as that is a bit abstract and requires some thinking out). Multiton is singleton but based upon a key, so very similar to flyweight, but not quite (since many instances may continue to be created). Best example of Multiton is a key-based DB connection pool like c3p0.

      Thoughts? Doubts?

       
    • uptown

      uptown - 2006-09-08

      Sounds good to me.

      So basically with both of them could we basically have each class be registered with the key or differenciating member (we may not even need that even .equals may suffice) and then assert after each constructor is called that there are no other instances equal to that one.

      I think i'm missing something here though that makes this a little more tricky though.

       
    • uptown

      uptown - 2006-09-20

      It is a little more tricky than this. I'm going to break out the discussion into sperate threads Multiton and Flyweight.

       
    • uptown

      uptown - 2006-09-21

      I see the following in the test.objects.xml in the source. I'm guessing its an example of the suggested xml format...

      <object-profile name="patternSample" metaphor="testPatternSample">
      <design-pattern>singleton</design-pattern>
      <classes>             <class>com.wideplay.Singleton</class>
      </classes>
      </object-profile>    

      We may want to make design-pattern specific elements to allow deviations or design pattern specific options...

      <object-profile name="patternSample" metaphor="testPatternSample">
      <singleton>
      <!-- Allow changes to which method gets an instance -->
      <instanceOf>getInstance</instanceOf>
      </singleton>
      <!-- All classes to assert this pattern on during the specified metaphor -->
      <classes>             <class>com.wideplay.Singleton</class>
      </classes>
      </object-profile>    

       
    • uptown

      uptown - 2006-09-21

      Actually its probably best that the classes element be a design pattern specific element (if we are to go that way) because all patterns won't have the same relationship to classes which implement it.

      <object-profile name="patternSample" metaphor="testPatternSample">
      <singleton>
      <class>test.Singleton</class>
      <!-- Allow changes to which method gets an instance -->
      <instanceOf>getInstance</instanceOf>
      </singleton>
      </object-profile> 

       
    • deje

      deje - 2006-09-24

      Yea that's a good suggestion. I think eventually we should standardize those names into schema. So instead of the current

      <myProperty>assertion</myProperty>

      It can be more spring-framework like:

      <property name="myProperty">assertion.</property>

      Then we can include specific xml schema for new design pattern packs. example:

      <object-profile>

        <adv-patterns:multiton/>
        <adv-patterns:classes>
           <adv-patterns:class name="com.my.Class"/>
        ...etc.

      Anyway will break this out into a new thread.

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.