Behavioral Software Architecture Language

August 2006

by Behzad Karim

Summary: Software architecture is a hot keyword these days for people in our profession. It seems everyone is out to discover the true potential of the software architecture and what it can bring into play for them. The basic idea of architecture definition is to design software structure and object interaction before the detailed design phase. Although serious architecture definition is being suggested for large projects only, arguably any software construction or implementation work must be preceded by an architectural design and approval phase. Get acquainted with BASL, a language that unifies software architecture definition with software implementation (coding).

Contents

One might rightly argue that there are at least a dozen well-defined standards and tools that can be used for defining software architecture. We do have standards and tools to define, communicate, and even generate templates for software design. Some of these tools can even work two ways by translating code to an architecture model and vice versa. Why then is there a need for another language or programming model?

Although there are plenty of ways to define the software architecture in terms of packages, components, and connectors (that is, the structure of software), when it comes to defining dynamic software behavior, we are unable to provide a definition for, communicate, or even clearly design them. However, the dynamic behavior of software is really what our software does after it rolls out into the production environment.

Most current, well-known (and established) techniques used for software architecture definition are from an era when software architecture was still a myth. While these techniques (and tools) do a great job defining the structure and components of software systems, they lack the ability to encapsulate and define the software behavior and various interactions with the environment against the dimension of time. Arguably these tools were not meant for the software architect as much as they were meant for the software engineer.

The basic need of the architect to define the essence of a software system in an abstract manner while providing the picture of the living system remains unanswered. We are either going too much into the implementation details or merely communicating the outer surface of the system. In both cases we are leaving out the most fundamental ingredient of software character: the dynamic behavioral aspects of the system. In too many projects these aspects of the system are being discovered in the detailed design or coding phase by the development team.

Facing Reality

Another dilemma is the ever-growing gap between the code and the original architecture of the system. We are using different tools and languages in the process of software construction. The software architect is using some kind of a modeling language while the developer is using a programming language. As a result, especially after the system rolls into production, documents, diagrams, and code get out of sync. Have you ever had to come back to revise a system you had designed in the past, only to discover that the architecture has no resemblance to the original design?

This analogy holds true for class diagrams, use cases, and test scenarios. The usual problem with these documents is that they all seem to become obsolete after the software rolls into production. These problems arise from the lack of a shared medium or a singular point of reference for the architecture and physical solution. Ideally, architecture and code are inseparable faces of the very same reality: the software system.

The software-engineering discipline has come a long way since the early days of its existence. Through its journey, ideas from other engineering professions have been utilized. One fundamental factor that differentiates our profession from other engineering fields is the nature of our labor, and more specifically, the outcome of our work. We start with thoughts, ideas, and basic visions and develop them into realities that can change the lives of millions. The end result of our labor is not merely a static product or commodity but rather a living, responding organism.

Software engineering as a discipline will continue to work with more complexity in building software systems. As if this were not enough, the users of these systems will require more intelligent systems, simpler interfaces, and richer functionalities. Software builders will need to handle greater amounts of detail to meet more sophisticated user requirements. Though not statistically proven, experience shows that as the scope, size, and dependencies of software systems rise, complexity rises exponentially. It is evident that complexity is a key concern that we would like software architecture to be able to address.

There are many approaches to software architecture published by respected authors in the discipline. While I respect and enjoy all research documents published on this topic, I would like to keep my list of key points in handling complexity to only two factors:

The top-down approach in software design. This factor emphasizes a top-to-bottom approach in designing the software architecture, starting from the top-most system (product or the big solution) and dividing it into subsystems that can be designed independently, and then approaching each subsystem iteratively in a similar manner to divide it into independent components.

Decomposition or breakdown of the system. This factor means designing components that are loosely coupled and have clear and intuitive interfaces. The precondition of building suitable components is having a clear idea of the dynamic behavior of the system and subsystems. Components should address the functional requirements of the encompassing subsystem while harmoniously fitting together with other components.

These requirements have fuelled the research and the creation of the Behavioral Software Architecture Language (BSAL). The main purpose of BSAL is to:

Provide an implementation model that can start at the system-architecture level, allowing the architect to define the system, subsystems, states, and dynamic behavior of the system and all the subsystems.

Facilitate a unified platform for software architecture definition (both structure and behavior) and software implementation (coding). BSAL is meant to be the common language of the architect and the developer.

Enable the architecture design of the system (including behavior) to be enforced in the implementation level. This enforcement can be achieved by the aid of the interactive development environments (IDEs). Separation of roles and authorization mechanisms can be clearly implemented in a BSAL development environment.

Use a platform that can be changed and enhanced easily by further contributions in the future (BSAL is based on the OOD-OOP model).

Why "Behavioral"?

To better understand the importance of behavior and why it has been magnified at the architecture design phase of BSAL, let's consider a real-world scenario. We have been given a task to design major enhancements on the membership system of a comprehensible business-to-consumer (B2C) Web site. To make the situation more critical, assume that the system has been built by a couple of previous employees who are not currently readily available to help us. Such a system would normally have features to facilitate creating new members, update member information, manipulate member rights, perform authentication and authorization, and provide member wallets (credit card, address, and invoice information).

Since our job is to be responsible to technically lead a major revision to the core membership system, our first priority would be to try to understand this system in its totality. Hence, after examining the working solution we would look for documents and blueprints regarding the architecture of the system. Assuming we are lucky enough to find some class diagrams of the system, we may initially feel relieved. However, upon further investigation and analysis, we would likely find the diagrams themselves to be incomplete and out of date. As frustration builds, in our search of understanding the overall architecture of the system, we would eventually conclude that nothing but the code itself can reveal the architecture of this system. We would have to roll up our sleeves and start reading the code line by line. The code is always the definite source of information that could reveal (although not easily) to us the architecture of the system.

What piece of information would help us most in visualizing and understanding a software system? Although discovering the interaction rules and interfaces of the system, obtaining the business analysis documents of the system, having up-to-date class diagram blueprints, and getting up-to-date technical design and requirements documents would help, having the original developer of the system explain the behavior of the system and explain the event-conditioning and state-change sequence of the system would be the most favorable choice.

This choice is favorable because software behavior and event/state changes are very difficult to be grasped without the direct help of previous designers of the system. Although the lack of up-to-date information is a definite disadvantage in this situation, being confronted with too much information can also lead to a disaster. Both ends of the information-availability spectrum are unfavorable situations.

An experienced architect would seek to understand the dynamic behavior of the system as it interacts and responds to other systems and user requests before even considering the changes or new features. In this particular situation, the dynamic behavior of the system would be deeply embedded in the physical structure of the solution (the source code).

It's important to stress that the behavioral aspects of a software system play a key role in revealing the true nature of it, which is why BSAL starts the definition of a software system by outlining the subsystems, states, and behavioral patterns.

Get to Know BSAL

Let's get acquainted with the simple and yet effective language for defining software architecture (and coding). While BSAL is an architecture definition language, it is also a programming language. Although there are other aspects of software architecture that could have been emphasized, the focus in BSAL has been on providing a generally simplified model of architecture definition while facilitating a flexible programming model.

Considering the behavioral aspects of the software systems to be most important, BASL emphasizes the definition of behavior patterns in the architecture definition phase. In fact, without defining the behavioral patterns of the system you cannot proceed to implementation of lower models in the system. The programming language syntax of BSAL could be any modern object-oriented programming language. While the principles of the language can be applied to any modern OOP language (and I certainly hope to see that in the future), C#.NET was used here to convey the BSAL ideas discussed. Before proceeding any further, it may be helpful to provide a role-based usage scenario for BSAL:

The software architect uses the language to define the major characteristics of the software system. Namely, system, subsystem, state, behavior, and message objects are defined by the architect. These are the high-level component definitions for any software solution.

The software engineer uses the direct output of the architect's work (the high-level BSAL source code) as the input to his or her work, provides detailed design, and starts implementing states, messages, components, and classes inside subsystems.

The analyst uses the BSAL source code to analyze high-level system breakdown and component definitions and understand the system behavior before proposing further enhancements to the system.

BSAL is based on the object-oriented paradigm. The important addition that BSAL brings into play is the common, standard usage of a few building blocks in software definition. These building blocks can themselves be created using a modern OOP language. The basic rule of BSAL is that every piece of code must be inside a system object. A system object itself can encapsulate smaller systems or subsystems. The system object can contain fields (attributes), must have at least two state objects, and can have behavior and message objects. Executable code can only be written inside state objects of the system, meaning that the system object (or subsystem object for that matter), behavior object, and message objects solely define the behavior and structure of the system (the architecture). However, almost all of the programmer's executable code will reside inside the state objects, which greatly simplifies the task of architecture design and carries the architecture down into the programmer's code.

Component Breakdown

Low-level components of BSAL could be implemented in any modern object-oriented programming language such as C#.NET, Java, or C++ (the details of these components are beyond the scope of this discussion). Presentation of a full working model of BSAL will be left as the main theme of a future discussion. The basic high-level components of BSAL are system, state, behavior, and message objects. These are the objects that the architects of the system usually define. These objects draw and define the basic boundaries and foundations of the system (see Figure 1).

Figure 1. The basic foundation of systems (Click on the picture for a larger image)

The system object is the top-most BSAL component. It is the object that encapsulates all other components of the system. It can be spread across multiple files, modules, and/or packages. A system can be composed of one or more subsystems. A system can encapsulate subsystems, states, behaviors, messages, and custom fields and attributes. The system must have at least two states, namely, initial state and final state. When the system is started, it immediately goes into the initial state; when the system is signaled to shut down, it goes into the final state. A system can have unlimited custom states.

A system has an initial state and a final state; can receive messages (input to the system); can check behavioral conditions so that it can change and manage states accordingly; can implement behavioral patterns by activating and finalizing states; and can send messages to other systems (output from the system).

public class member : System
{
protected State
createMember;
public member(
State istate, State
fstate) : base(
istate, fstate)
{
}
}

The state object defines a stage that the system can go through to perform a specific task. State definitions organize work units in a certain logical order. States implement the primary functionality of the system.

A state object has two required methods named entry() and exit(). The entry() method is called when the state is activated; the exit() method is called when the state is signaled for completion. A state object can have unlimited custom methods.

A system can change states internally, or it can change state in response to an outside interaction with other systems or environments. (For example, receiving a message from another system can trigger a change of state in a system.) The common place where a state change is implemented inside a behavior object or another state's exit() method.

A state object has an entry() and an exit() method, can be activated through a behavior object or another state object, can complete itself, must check the behavior objects related to it when completed, can have custom properties and methods, and can run as a separate thread of execution (parallel states).

The behavior object is where the behavioral patterns of the system are defined. Behavior definition is the heart of the state management of a software system. Typically, a behavior definition contains one or more conditions-related method calls to complete and/or activate certain states of the system. Behavior definitions should not contain any executable code other than those resulting in change of state, setting a field or attribute, or sending a message to other systems. The sole purpose here is to define the behavior of the system under certain conditions or circumstances. A behavior object basically encapsulates conditions, changes in attributes, sending messages, and completing and activating states.

Good for the Profession

A message object encapsulates the synchronous/asynchronous information flow between different systems. A system object can only receive message objects that have been defined for it. A message definition typically contains a message ID, a message header, and a message body. The underlying implementation of messages could be left to the specific environment and framework in use. The behavioral pattern of the system is checked either when the system receives any new messages or (alternatively) when any state inside the system is being completed.

As information technology problems continue to get more complex, software engineers need languages (and programming models) that can hide and encapsulate greater levels of detail. As we discussed here, the traditional OOP development analogy backed up with software modeling notations can be limiting and at times cumbersome. BSAL merges the architecture (structure and behavior) and the executable code into a single source. Architects and software engineers need to communicate, share, and build ideas. To come up with alternative or improved solutions for live systems, they need to quickly grasp the essence of software systems. Being able to understand quickly and precisely a software system is a great virtue. BSAL is a possible answer to these needs and hopefully a positive step in opening up new horizons in the future of the software-engineering profession.

For an application of BSAL to software factories by the same author please refer to this article.