Click here to Skip to main content
13,292,205 members (55,715 online)
Click here to Skip to main content
Add your own
alternative version


36 bookmarked
Posted 11 Apr 2005

Refactoring to Adaptive Object Modeling: Strategy Pattern

, 20 Jun 2005
Rate this:
Please Sign up or sign in to vote.
Strategy methodology maintains that the operations and business rules or code flow of a class should be held as a collection of properties, as opposed to single method calls, which can be changed at runtime.


Adaptive Object Modeling is a relatively unrealized concept in object oriented design that has found some roots in advanced development processes. It allows that applications are in continual flux (or their requirements are) from adjustments to business rules, environments and user requirements. Its precepts are that using metadata for business objects, rules and process flows, instead of hard coded, static method code, makes the application more flexible to user/client needs. The AOM design model also requires that certain domain 'facts' are maintained, i.e. that there are controlled interpretations of the effects of the 'immediate' changes from user-generated metadata.

Adaptive solutions offer us a way to make applications more configurable (regarding workflow) to the end users. It is not a 99% solution and, to my knowledge there is no end-to-end solution that meets all needs, simply because those needs are more directly defined by the business requirements. However, since business requirements change frequently, writing immutable code flow logic leaves very short lives for code. Even the online industry is feeling the need to configure dynamically: if you are a subscriber to most web portals like Yahoo! or MSN you have a user configurable home page where you can decide which items of interest you would like to display on your page.

Most portal technologies are indirectly pointing us to a more adaptive model, simply because they are configurable by end-users or power-users. I see adaptive technologies like Adaptive Object Modeling in the same light as a web portal: some functionality is needed to be coded by developers, like database and business logic, but where and when this logic is implemented should be (following business trends) decided upon by business experts, not developers. Some adaptive models incorporate the non-meta-data into tier models tightly coupled with tier meta-data, which is one way to do it, but I prefer to let the EUD (end user developer) have the hand in how business data is handled, and simply allow the AOM framework to give the actual implementation of when and where back to business experts (which most developers don't have the bandwidth to be).

To better understand and practice the techniques of AOM design, I am writing this and several other articles that explain the usage and conversion (or refactoring effort) from a static code model to AOM design.

This article will deal with Strategy methodology of Adaptive Object Modeling. Strategy methodology maintains that the operations and business rules or code flow of a class should be held as a collection of properties, as opposed to single method calls, which can changed at runtime. A Strategy pattern is a set of algorithms. So a Strategy pattern as it relates to AOM is a group of different strategies that can be dynamically added as business rules to an entity at runtime.


Using a Strategy design method is an interesting way to extend the configuration possibilities of simple class object methodology. It gives a way to define a class' operations and rules dynamically, or at runtime, from a database, configuration file or user interface. Virtually any meta-data source can define the operations for a given AOM class structure. The Strategy design method uses, in this example, interface contracts and reflection to help define the limits of the operational calls.

Here we see the exact Adaptive Object Modeling UML for the Strategy class pattern based on the Design Patterns GOF95 model. Notice that the Entity object accepts and has specific operations (or strategies) associated with it. The strategy deals with actual business rule and operational rule implementations.

How to use the code

We start this refactoring example where we left off from our other example article Properties. We still have the same entity and entity types, and now we would like to dynamically add some operational methods or Strategies. To accomplish this we need to create a class to hold our dynamic interface contracts that are loaded during runtime. This takes the form of a simple container (or entity-attribute type) object that holds the interfaces or contracts for speaking to different strategies. This is loaded with metadata at runtime for the specific object operation that we wish to implement. Notice that we have added a collection object OperationsCollection, which contains the shared operations between the entity and the entity type:

public interface IOperation
    void OperationMethod(object[] parameters);

//Collection of attributes

public class OperationsCollection
    public void Add(IOperation obj)
        //.....addition code to collection


Here we see that the EntityType object from our last example has an added parameter of type OperationsCollection. This operations collection will allow the Entity object to have dynamically loaded meta-data driven business rules associated with it at runtime. Now we can store any given business rule we like within our class objects, without recompile:

public abstract class EntityType
    private string _typeName;
    private Type _type;
    private EntityAttributeCollection _attributes = 
                         new EntityAttributeCollection();
    private OperationsCollection _operations = 
                         new OperationsCollection();

    public EntityType(string name, Type type)
        _typeName = name;            
        _type = type;    
    public string Name
        get{return _typeName;}
        set{_typeName = value;}                    
    public Type TypeOf
        get{return _type;}
        set{_type = value;}                    
    public EntityAttributeCollection Attributes
        get{return _attributes;}
        set{_attributes = value;}                    

    public OperationsCollection Operations
        get{return _operations;}
        set{_operations = value;}                    

We have also created functional method objects inheriting from IOperation, which define the exact method operations we will allow to be adapted to our entity object. Having the interface allows us to tie that interface to any class method we wish, as long as that class implements IOperation.

Note: The operational methods could be contained in other assemblies, the namespace encapsulation becomes unimportant, because you can add attributes or methods via the metadata, without any concern to its source at compile time. Also the operation method interface IOperation could be changed to dynamically define strongly type parameters as well, but this will be saved for either another article or your own invention. Remember, reflection is used heavily as we will see in the factory class, and is the key to dynamic representation of contractual interfaces.

public class JobOperation1 : IOperation
    void IOperation.OperationMethod(object[] parameters)
        Console.WriteLine("..." + this.GetType().Name + 
                        ".OperationMethod method called.");
        foreach(object obj in parameters)
            Console.WriteLine("... parameter Type:" + 
                          obj.GetType() + " Value:" + obj);  

public class JobOperation2 : IOperation
    void IOperation.OperationMethod(object[] parameters)
        Console.WriteLine("..." + this.GetType().Name + 
                      ".OperationMethod method called.");
        foreach(object obj in parameters)
            Console.WriteLine("... parameter Type:" + 
                       obj.GetType() + " Value:" + obj);  

We are now ready to focus on the AOMFactory class, which is a static factory implementation loosely based on Deyan Petrov's DataSourceFactory. The factory is where we will actually load our runtime data for this example. Our example code will use an XML config file for the actual meta-data, but in actual project code, as I stated above a variety of sources are available, not in the least, the client or user interface. Remember, this factory class is only for this example, and while I would recommend a factory or builder pattern for this piece, it is up to you the developer to find the suitable method for loading your classes from meta-data.

The first piece of data we get after this revision to our Properties example is the meta-data for the operation. We will use this data to build and define all the possible types of operational interfaces we can load to our entity types, making them available to specific entities. The class with the methods we wish to add inherits from the IOperation interface, providing access to its methods directly.

string name = Convert.ToString(hash["name"]);
//the name of this attribute
if(name == null || name == string.Empty)
    throw new FactoryException("No operation name specified.");

//get the attribute type
string strOperationType = Convert.ToString(hash["type"]);
if(strOperationType == null || strOperationType == string.Empty)
    throw new FactoryException("No Type specified for operation " + name);
//get the type for a strongly typed parameter
Type operationType = Type.GetType(strOperationType);
if(operationType == null)
    throw new FactoryException("Could not load class Type for type " + 
                         strOperationType + " for operation " + name);

Here we make sure the class implements the interface, and creates an instance of the interface from the class type that holds the wanted operational methods. As we said above this gives a lot of flexibility to the business flow, and allows different assemblies to provide new data on the fly.

Type interfaceType = 
if(interfaceType == null)
    throw new FactoryException("No interface of type IOperation " + 
                                   "exists for operation " + name);    
IOperation operation = 

if(_entityOperations == null)
    _entityOperations = new Hashtable();


The config file defines the different operations by name and their implementation classes full type name. As we said above, the actual operational namespace can be internal or external. The meta-data from the config file appears thus:

       <entityOperation name="JobOperation1"
           type="Strategy.ImplClasses.JobOperation1" />
       <entityOperation name="JobOperation2"
           type="Strategy.ImplClasses.JobOperation2" />

Next we check to see if the hashtable that will hold our Strategy interfaces exists and contains the current data. If not we will add the new operation to the entityType object.

EntityType entityType = (EntityType)Activator.CreateInstance(entityTypeOf,
                                    new object[]{name,entityTypeOf});
foreach(string attribute in attributes)
foreach(string operation in operations)

The meta-data from the config file appears as below. Notice the operations XML node. This is where we put all the possible operation types by name for each EntityType instance. The operation names are comma delimited. This is how we define which strategy and business rule relationships we will associate with the entity instance.

    <entityType name="ExecutiveJobEntityType"
        operations="JobOperation1,JobOperation2" />
    <entityType name="EmployeeJobEntityType"
        operations="JobOperation2" />

We now are at a point where we can test our code.

Here we see that the entity is first established from the entity type and its operations have been called.

Expanding the example

How can we expand this example to functional code? We need to establish how the operational methods influence the program flow, and define our entity relationships and entitytype relationships if applicable. These items we will cover in the next article.

Points of interest

This is the third installment in the series I am writing on real world adaptive object modeling. All examples and the bulk of this article are taken from my professional experience as an architect. The examples given are templates only, and the designer must keep in mind that they are the ones who must decide where different patterns, if any, may be best used in their code.

Deciding to perform a refactoring effort from existing code to a pattern or enhanced design model must be weighed on the necessity and the need of the code itself. Patterns and Adaptive models are only design templates, helpers to accommodate better overall design. I must stress that making an effort to use advanced design methodologies will strengthen your overall design ability, but like your basic coding skills, it is something that is to be learnt and cultivated.

If this or any other in this series on adaptive object modeling design is helpful to you or you have questions or comments, please e-mail me at:

Related Articles

Other articles in this series include:

  1. Type Object
  2. Properties
  3. Strategies
  4. Entity-Relationships and Accountability/Cardinality.
  5. Ghost Loading, Data Mapping and more...
  6. Interpreter methodologies (coming soon).
  7. Discussions on Practical Project usefulness of design.
  8. Adaptive Object Modeling: Final discussions and MVC.


This is the first revision and is the third installment in a series.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Christopher G. Lasater
Web Developer
United States United States
Christopher G. Lasater

I am also a published author, please check out my book:
ISBN: 1-59822-031-4
Title: Design Patterns
Author:Christopher G. Lasater
More from my web site

You may also be interested in...

Comments and Discussions

QuestionComposite??? Pin
Nirosh21-Jan-07 22:50
memberNirosh21-Jan-07 22:50 
AnswerRe: Composite??? Pin
Christopher G. Lasater22-Jan-07 6:02
memberChristopher G. Lasater22-Jan-07 6:02 
AnswerRe: Composite??? Pin
Christopher G. Lasater22-Jan-07 6:06
memberChristopher G. Lasater22-Jan-07 6:06 
GeneralRe: Composite??? Pin
Nirosh22-Jan-07 22:43
memberNirosh22-Jan-07 22:43 
GeneralRe: Composite??? Pin
Christopher G. Lasater23-Jan-07 5:19
memberChristopher G. Lasater23-Jan-07 5:19 
Really I am not sure what point you are trying to make. This article is actually about a year old, and was only intended as an example, not a project solution to requirements, so......
As far as relationships, if that was what you were asking about (kind of unclear) then you can look at Entity Relationships.

Christopher G. Lasater

GeneralUsing Strategies Pin
Philip Laureano11-Jul-05 20:15
memberPhilip Laureano11-Jul-05 20:15 
GeneralRe: Using Strategies Pin
chris lasater12-Jul-05 5:45
memberchris lasater12-Jul-05 5:45 
GeneralRe: Using Strategies Pin
chris lasater12-Jul-05 5:47
memberchris lasater12-Jul-05 5:47 
GeneralRe: Using Strategies Pin
chris lasater12-Jul-05 9:44
memberchris lasater12-Jul-05 9:44 
GeneralRe: Using Strategies Pin
Philip Laureano12-Jul-05 19:31
memberPhilip Laureano12-Jul-05 19:31 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.171207.1 | Last Updated 21 Jun 2005
Article Copyright 2005 by Christopher G. Lasater
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid