Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Adaptive Object Modeling: Final Discussions and MVC

0.00/5 (No votes)
21 Jun 2005 1  
This article explains how client interfaces can be dealt with via the pattern. Also gives some very good reasons why an interpretive pattern methodology should be used over more static code, and attempts to explain how and why business development solutions can implement the pattern.

Introduction

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 how client interfaces can be dealt with via the pattern. This article will also give some very good reasons why a interpretive pattern methodology should be used over more static code, and attempt to explain how and why business development solutions can implement the pattern and how it allows the business to interact in a more intuitive fashion with the code produced by developers. We will also talk briefly about how the example might be handled in a more visual application form, like a web application, including security, dynamic content generation, and global variables (like user information from a logon screen).

Who this article is for

This article is written primarily for architects and business IT development managers, as well as developers who have some advanced reflection and design experience, and anyone familiar with AOM or other like pattern methodologies, who while interested in these patterns, have not seen practical ideas to the patterns usage. This article is the last in the series (not the last to be written, I have skipped around a bit), and deals not so much with the example code, but more with ideologies that can be extrapolated from the example. This article is designed to fire new ideas in your mind. This series of articles will be the starting point for a AOM framework that I will be releasing later this year.

Background

MVC or Model View Controller pattern, has been around since Small Talk, quite a while. It was the first real dynamic client pattern, but since then others have sprouted. Aspect Oriented Programming is another newly hashed out pattern. So it stands to reason that AOM would also support such a client featured methodology.

Okay, the first thing we want to understand is that language interpretive programming has drawbacks and advantages.

Obvious drawbacks include the (perceived) complexity that is needed to abstract program flow to a point where business power users can make programmatic decisions, as opposed to having the developer code those controls into static compiled code. Perceived complexity is the main drawback. Developers who have never developed in reflection heavy environments, who have difficulty thinking abstractly about their code, or who have no formal architecture experience will have trouble with any of the more flexible patterns like AOM, Aspect Oriented Programming or even Model View Controller. Changing this is not only the onus of the developers, but also rests on the shoulders of the IT managers, who for decades have relied upon their developers to make these types of programmatic decisions, and the general business organizations who are either not knowledgeable enough about some of the options or do not support a mature enough development staff to be able to leverage more advanced programming schemas. But as businesses start to recognize that their development resources are being allowed to interpret business knowledge that is best handled by the business experts, and this is costing money in lost time and functionality, businesses are beginning to see less disadvantage and more advantage to language interpreted modular programming. Also more is expected of computers today, 'smarter' more runtime compliant and flexible computing solutions are gaining favor over less complex, static program flows. Evidence of this is seen in user configurable web home pages, that allow individual users to reconfigure their web experience to their specifications.

So the advantages in this light are more intriguing than the disadvantages. We developers have to write code that we are interpreting from the business requirements handed to us by the business experts and users. No matter how well we interpret these instructions, we are in some way not entirely accurate in our assumptions. We are in general coding into our programs what we think the users and business units want from us. Especially when developing on waterfall style project iterations, this can lead to huge holes in the business needs of the software. This results either from poor requirements gathering or poor interpretation of the requirements. What the business would really benefit from is more configuration options, allowing power users to determine on the fly the way a program operation flows. Static code solutions, while easier for developers to understand and with less setup and continued maintenance on the part of the business, can only have a relatively short lifetime, especially in regard to ever changing business goals and requirements. What if development managers and power users could negotiate with development teams to produce only the basic, non-decision making functional code, and keep the direction and programmatic flow of the application as their own domain? What if whole sections or compartments of code could be separated and controlled not by a developer's compiler, but by the very business users that use the software? What if a power user could become the director of the result of the collective work of different development teams, each building a separate piece of a larger picture, and actually make the decisions on where and when these different pieces could be brought to bear in the program flow? All this is possible in a language interpreting system.

The Flexible Client Interface

Let's start this discussion by describing what many people have had various questions and skepticism about, how the AOM language interpretive pattern is seen via the client interface. In this example I am using a simple console interface, which has very simple recursive methods that allow access to the operational methods and attributes. I re-wrote this example from the previous article in a day, so don't expect any complex answers to questions like chaining methods, web control interfaces or any advanced client usages, this is just an example to get the idea (I will be releasing an open source framework later this year that will include a complete solution for almost any development need, using AOM as a base). I will use the example to give you the reader a very general, but in depth view of how the AOM model is used via the client. Even so this is proving to be a very long article.

To make the abstraction less onerous, let's think about each entity as a separate screen in an application. Each screen has its own attributes (like a web page might have text or controls with data) and operations (think about buttons on a screen). Operations of course might have linkages from one to another, but that will be part of another discussion.

Running the application, we see the console screen come up with the entry point to the application, asking us to 'Process another entity'. This would be the piece of the application similar to a menu selection, asking you to select a particular menu entry to take you to a screen. If you typed 'Y' or 'yes' and hit Enter, the screen now shows you the choices, indicated by 'Available Classes:'. The choices, while not actual compiled classes, are indicators of the types of functionality you might desire, each set up by the power user (you, for this example) in the meta-data (the UserConfiguration.config file). Each type has its own attributes and operations.

The meta-data gives us an idea of how we got our particular menu items. We can see that each item displays more than just the entity name, but also the entity type, which acts as an abstract parent class, the attributes associated with the entity, and the operations linked to the entity. Remember the entity type holds the attributes and operations that are common to all the children, and in the entities we see below are the extensions to that functionality, much the same way we subclass compiled classes and add functions and methods to the new class. Instead of compiling though, we leave the decision to the runtime interpretation of the meta-data.

<entities>
        <entity name="ExecutiveJob" 
            type="AOMImpl.EntityImpl.Entity" 
            entityType="ExecutiveJobEntityType"
            extendedAttributes="JobLevel,FirstName,LastName"
            extendedOperations="WriteAReport" />
        <entity name="EmployeeJob" 
            type="AOMImpl.EntityImpl.Entity" 
            entityType="EmployeeJobEntityType" 
            extendedAttributes=""
            extendedOperations="GoofOff" />
        <entity name="ContractorJob" 
            type="AOMImpl.EntityImpl.Entity" 
            entityType="EmployeeJobEntityType" 
            extendedAttributes=""
            extendedOperations="" />
    </entities>

Now we see our actual entity detail. Think of this as part of the program that displays a screen, with entry controls like text boxes. We can change the value of each attribute by selecting the attribute name (i.e., type 'FullName' to select the System.String attribute for that name). Again, in an application with more visual depth, like a web or forms application, these attributes might be either displayed text, hidden variables, or local variables, each with a richer selection of attributes, which again could be defined in detail by the meta-data.

Note: To define attributes for a visually rich application, your meta-data could specify the type of control, the method or operation which supplies data (as in the case of a drop down box that fills with data from a method call), validation controls that might link to the control, or any other common attribute you wish.

Now, we have defined the actual displayed attributes by the meta-data, let's see how we might change what we see on the 'screen' while still in runtime mode. This is quite a different approach to conventional runtime applications, which have all their screen functionality set up by the developer's compiler, and at runtime is quite static.

Below we see the meta-data for the EmployeeJob entity. Notice that the extendedAttributes XML attribute has no values, since the EmployeeJob entity relies on the ExecutiveJobEntityType entityType for its base attributes.

Now let's change something. Let's add into the extendedAttributes XML attribute the value 'JobLevel' which indicates that we want to add the defined attribute from our entityAttributes XML section.

Attribute definitions section:

Now let's refresh our console screen. Hit tilde {~} to escape the operation, then type 'Y' to refresh the attributes. Now you can see that the 'JobLevel' attribute has appeared!

Now let's look at the operational methods. When we escape the attribute selection screen (Hit tilde {~} to escape), we then can move to the operation selection screen. It functions much the same way the attribute screen does, except when we actually select an operation, like GoToLunch, we can then access this method, inputting data (and receiving results, if we wanted to).

Okay, so let's look at how the client can access a very basic operational call. Remember, this is not a very complex example, it is only to give the general idea. In a real world AOM framework, the operational methods are defined in such a way that they can only accept the exact inputs, possibly using reflection to determine this instead of an interface, and would have input validation and possibly even parameter mapping as an over layer, as in the case of mapping attributes as text boxes that then get sent to the different parameters of the operation.

For this example, we use an object[] parameter array, which accepts any number of inputs. We can enter input as text on the screen, and hit the 'Enter' key to add a new parameter. You can hit the tilde {~} key anytime to add parameter values and see the values you entered returned to you.

You can alter the operations that are associated with the Entity or screen the same way you do it for the attributes, by adding (or subtracting, which is not in the scope of this example) the needed operation key names to the extendedOperations XML attribute for the entity meta-data you wish to add it to, which is defined in the entityOperations XML attribute section:

Operation meta-data:

What is the usefulness of this? Well suppose you had a screen that you needed to change every month to add another section of functionality, or another button option, or another display field. Project iterations of this frequency are very difficult to manage, especially as the project grows in size and scope. But suppose you were using the AOM model, and you had three development teams that were each working on a separate piece of modular code to be released in a staggered fashion across three month release dates. As each team released its piece, the power user could decide where and when to add the new functionality. Let's say that a new field needed to be added to the screen, to be filled in and sent back to an operation (introduced in the same release). The power user could easily add the field and map it to its operation, and if a roll back was needed, that could be done just as easily, at anytime by the power user. No costly and difficult compile is necessary. And the power user, which might be a business expert, could decide the best place in the application to add the new functionality.

This also speaks to an enhanced user experience, since most applications today are relatively static in their presentation. But a power user could run through his/her changes and if a certain piece did not flow as planned, it could be removed or added into a different place with relative ease. I say relative, because as we will discuss later, the power user's effectiveness is based solely on the ease of use and cohesion of the power user's meta-data user interface.

You can play around with moving through the different screens and changing the meta-data as you like, exploring the different configurations you can come up with. You can even compile other more functional methods and see how the basic example framework interacts with your code (remember to follow the schema of the UserConfiguration.config file). This is where we leave the remainder of the article to your imagination, and discuss in more detail other considerations regarding this pattern.

Security

Okay, so we now have a basic understanding of the way the client interface might be incorporated into the AOM model. So now let's talk about some basic security considerations. First of all the typical ASP.NET security model is not really useful here, because instead of multiple source pages, we would have a single page which would act like a URL-redirect portal, changing content according to your interpreter engine at runtime. If we built a web front end to our AOM framework, we would have to build all content at runtime. So security would have to be an internal part of the AOM framework. How do we accomplish this? We would have to set up a type of subsection of the AOM framework for interpreting meta-data in a security related fashion. In other words we would have to set up security in our meta-data much the same way I do it in the BaseWeb security example article, with regard to Entity level security as opposed to page level. We could add a roles based system that allowed access to certain Entity classes, or pages, in the AOM system, by role. We could even have a system that could display certain content only by role.

The second consideration is how do we obtain authentication data in the application. My suggestion is accomplish this the exact same way you might in any other .NET web application, via a login screen or Windows authentication method ("Windows", "Forms", "Passport" and "None"). You could have the user logon, and based on the logon data given, other data could be mapped into session variables, like user data pulled from a database. The AOM Framework could have a special subsection setup for this purpose, that defined which data the authenticated user would need in order to pull session specific data, and methods that could be mapped to specific entity classes that provided special rules or Entity Relationships, for each type of access. In other words, when a user logged in, all the pages (Entity classes) that they had access to could be chained together, and any they did not have access to would not be part of the chain. The top parent Entity class could hold certain attributes that were required to be filled or an error would occur.

Let's discuss an example of how a basic authentication cycle might work. First the user logs into a forms window, that allows access to everyone. That logon page redirects to the AOM framework entry page, which sits in a secure directory below the logon page, giving the AOM framework page access to the authentication IIdentity data for the session context, while limiting unwanted access. The entry page to the AOM Framework should validate authentication data (if applicable) and based on the meta-data, load into session variables the user specific data needed. Meta-data should be specified for the operations that should be called and the session variables that this data should be loaded to. Meta-data on the specific Entity classes (pages) can then map to the session variable data (again via the meta-data) and on load of each page use this data to populate attributes, or supply input for operational methods. Next, based on the user's role, the Entity Relationships can be set up, and loaded into session; each entity can have as a relationship another entity, which could be used to map the flow of the application. In other words, let's say the user has a role that allows view of EmployeeJob. Let's say that in the meta-data (which is out of scope of the example), a relationship is set up to link EmployeeJob to ContractorJob. So a user that could see EmployeeJob, could also see a link to ContractorJob, and go access that class as a web page.

Global Properties

Global properties are a central issue with how the AOM pattern interacts with its environment. If you have variables or values of any kind that need to be shared across the user experience or the application, meta-data would have to be generated to deal with how this is done.

Session variables, for example, could be mapped from methods derived by the combination of class reflection and meta-data into named session variables, and these variables could be mapped in turn to individual page or request attributes. EntityTypes or Entity classes could be used to specifically map global variables or attributes via a relationship to any other entity class where this was needed.

Remember, Entity classes are just definitions. They can be used for a whole host of practical applications, including variable types or class types, page or screens; they can be stored in session variables or cached. How you might use them in a framework depends on your particular need.

Operational Chains of Dependency

Chains of dependency or Entity Relationships will be discussed briefly here, and will be discussed in depth in another article. We have discussed already the various ways that Entity classes can use relationships between each other to facilitate code flows. Obviously for a UI example, we define our Entity classes as screens or pages, defining the UI experience with the controls, properties, content and functional items (like buttons and manipulative controls) and links to other Entity classes. And so in a UI implementation of an AOM framework, the relationships might be indicated as how the pages interact between each other, or might indicate how security is established. In other types of implementations we might see relationships as groupings of business rules, Chains of Responsibilities, or any other type of relationship pattern needed.

Operational dependencies are a bit of a different animal. I have had a few questions on this subject and will attempt to describe some solutions here. Usually when we code two different operations together we use the results of one to either make a decision or to facilitate the function of the second. In the AOM model, operations are comprised of individual pieces of code that does some separate component of work.

Let's first talk about the different ways operations can have relationships.

Let's say we have two chat programs that we want to send some data to, and we want to call first one then the other, and do not care if one fails and the other does not. We simply set up in our entity class a relationship to another entity that contains the first operation, and then in that entity set up a relationship to another entity that contains the second operation. We specify how the relationship details occur, i.e. the first entity class has as an operation to the second entity class, with the default operation set to the first chat program. The second entity class containing the first chat program has its default operation as the third entity class, with its default operation set to be the second chat program. The second entity class' attributes are all the parameters needed for the first chat program method call, and each needed attribute is mapped to that operation parameter (via the meta-data). The third entity class is defined in a like manner. So when we call the first entity class, it contains a reference to the second entity, which has the required first operation call as its default and is fed all the parameters needed for the operation, each attribute mapped to the indicated parameter. When that operation is finished, we move to the next operation in the third entity class, and process that operation as well. Thus we allow for a chained operation call. As you see, we do not move away from other design patterns with AOM, but rely on them.

The Power User Experience

The usefulness of the AOM framework to your power-user is based on the ease of their user experience. I must stress that power users will not find your AOM framework useful if it is not easy to use, full featured and offers a wide range of functionality. For example, the meta-data UI that maps a method to pull drop down data from an assembly should list the possible methods, their output, and give an easy to use interface to link the desired control to the desired method. The power user at first may be your development manager, or even yourself, so you may not see the need for a terribly interactive UI, but as these types of applications become more useful and have a wider audience, this will change. Power users may end up being business experts who have little if any development knowledge, and can become frustrated with a poor UI experience from your meta-data administration screen.

Modular Development Cycles - Iterative or Agile Design

The optimum way to develop with an Adaptive Object Model framework is of course iterative. Agile processes seem to me to be the logical extension of the AOM model into the development cycle. While businesses have increased their speed and scope, IT applications have died on the project vine while the businesses stride ahead, or change their minds. All too often project life cycles are getting shorter and shorter, causing the business to delay its own needs to plan new development, even before the older development needs are met. To change this, and allow IT to catch up to the the ever expanding and changing needs of businesses, software development has to change too. Several methodologies have sprouted up around these ideals, Agile Processes, Extreme Programming, iterative projects (as opposed to waterfall) have all contributed to easing these development burdens, or enhanced the process in general. But no matter how smart your development cycles are, the software remains the same. We still compile static solutions into a fluctuating world. What needs to change? Both software and the business approach to software has to change to facilitate a sleeker, more intuitive development process. How do we do this? When I first came in contact with the AOM pattern, I saw one true thing of all in the structure: you can call any operation you want whenever you need it. In other words the business logic of when and where could be determined in a dynamic fashion. Why is this important? Well, the first thing we have to realize is where we are now. Currently most businesses are relying on very old software development and integration processes. If new ones are introduced, they require a lot of maintenance and process to continue to function properly. Even if these practices are effective, and the advantages are many and easily seen, effort is required for them to flourish.

That is not to say that some of these changes are not good. But even the best ones require a lot of planning and overall agreement by all the actors. This is fine in setting up who does what and when, and what is produced at what time, but does nothing to fix the problem of software: it is still static.

What I propose is another solution. I say I propose, even though the idea is not new or really centrally mine, but since I am the presenter of this article, I propose this as a restatement of some already known and obvious solutions. What if businesses took a different attitude towards how they develop software, and this attitude is: build what you need today today, and build what you need tomorrow tomorrow? I know, this is more akin to agile or extreme programming, but when taken in the context of the AOM model and modular programming, it makes a lot of sense.

Imagine that you as the development manager would get requirements for a web application, not what pages to build, but only what background processing logic to build. You hand these very technical, and not very decisional requirements to your developers, who build just that particular piece. When they are finished you talk with your business experts, and they tell you that they want to see this button and these fields on this page, and click, click .. boom, there it is, displayed on the page and functional.

What would this kind of development require? Not a huge change on how the businesses send out requirements, but more on how the development team manages expectations. With AOM, you would favor a more iterative project cycle with a 'develop what you need' approach.

The Considerations of the Future - Language Interpreted Algorithms

I have seen the future, and it is smart. Smarter computing I mean. Or rather more intuitive, more responsive to the user, faster to change. Much has been said towards the future of computing, and most of it leans toward having more intuitive interaction with the user. So when developing software applications, this should also be a consideration. Software systems that relate in a more direct fashion to the actual users, are favored even today. In the future, putting aside fears and concerns over complexity will be a necessity in order to develop more intuitive systems.

Considerations

This is the fifth 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 need of the code itself. Patterns and Adaptive Models are only design templates, helpers to accommodate better overall design. I might stress that making the effort to use advanced design methodologies will strengthen your overall design ability, but like your basic coding skills, it is something learned and cultivated.

If this or any other in this series on adaptive object modeling design is helpful or you have questions or comments please e-mail me at chris.lasater@gmail.com.

Related Articles

Other articles in this series include:

  1. TypeObject
  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. Discussions on the AOM framework, UI, and advanced concepts.

History

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

Credits

Thanks to: Joe Yoder, Ralph Johnson, for their various articles on the AOM pattern, Martin Fowler for his interest in my articles and his work on the Accountability pattern, and Doga Oztuzun, for his insight and sharing of his relevant project data. Also to anyone else I have forgotten.

License

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