Reduce Development Hours With Pattern-Oriented Development

Reduce Development Hours With Pattern-Oriented Development




Purpose of Article

To explain the flaws in what is generally considered Pattern-Oriented development and to show how to conquer those flaws by putting a retooled Pattern-Oriented approach to work.

To stress that informal design patterns make up a large portion of the patterns discovered during Pattern-Oriented development.

To list examples of a few design patterns of the Framework as found in a number of Web applications developed by the author – add functional value to an otherwise pure theoretical conversation.

To show that design patterns can and often depend on other design patterns.

In summary, to give you a marginally different viewpoint of design patterns, stress the importance of Pattern-Oriented development and thereby instill the need to look into design patterns and software frameworks more closely.

Background

“We adopted nimble/Scrum, Test-pushed Development and we are object oriented. Our productivity certainly improved in comparison to what we experienced before. But why do our projects nevertheless overrun? This is very frustrating. There must be something else we are we missing… “

There can certainly be a multitude of reasons. for example, do you have thousands of lines of CSS because the developers did not understand how to separate positioning from style and how to “extend” CSS classes? without of skills certainly could be a huge contributor to the without of success that development teams experience.

More than often it is a matter of emphasis not being placed on Pattern-Oriented Development. In general, Pattern-Oriented Development greatly lacks applicable and valuable coverage in the Information Technology space. Without being pattern-oriented, systems could end up containing twice as many lines of code. We also know that with an increase in lines of code, the complexity of a system exponentially increases.

Does this average you have to look for where you missed the Strategy, Adapter, or Bridge, etc. pattern in your system? Looking for where you missed the formal design patterns is likely not where you will find the answers. The issue is more likely the without of discovering and acting upon informal design patterns in your system.

Design Pattern Objections

Let’s look at the objections against design patterns first and then at how to truly do it right.

Patterns have been criticized widely and rightly so. Here are some objections:

1. The need for design patterns resulted from using computer languages or techniques with insufficient abstraction ability. Peter Norvig provided a similar argument. He demonstrated that 16 out of the 23 patterns in the Design Patterns book (which is chiefly focused on C++) are simplified or deleted (via direct language sustain) in other languages.

2. Design patterns without formal foundations. At an OOPSLA conference, the Gang of Four was (with their complete cooperation) placed under a show trial in which they were “charged” with numerous crimes against computer science. They were “convicted” by 2/3 of the “jurors” who attended the trial.

3. Design patterns do not differ considerably from other abstractions. Some authors allege that design patterns don’t differ considerably from other forms of abstraction, and that the use of new terminology (borrowed from the architecture community) to describe existing occurrences in the field of programming is unnecessary.

4. Design patterns rule to inefficient solutions. It is almost always a more efficient solution to use a well-factored implementation instead of a “just barely good enough” design pattern.

shared Definitions of Libraries and Frameworks

If you look at Internet articles you will encounter Library and Framework definitions such as the following:

· A software library is essentially a set of roles that you can call, usually organized into classes. Each call does some work and returns control to the client.

· however, a software framework embodies some recondite design, with more behavior built in. In order to use it, you need to insert your behavior into various places in the framework. The framework’s code can also call your code at given points.

Software Framework Redefined

Here is my view on software frameworks:

A software framework is a set of design patterns (formal and/or informal) accompanied by the code necessary to take care of the shared functionality of the design patterns and to expose the framework part functionality to the developers.

Frameworks are almost always accompanied by what people describe as a library. for example, you will find, in the framework described in this article, elements that get registered with the framework which provides some functionality for the elements. This could be described as library functionality, but this is essentially the Decorator pattern.

Software Frameworks are all about design patterns, elimination of repetitive work, and are used to speed up development. They are used to streamline software development by allowing designers and programmers to devote their time to meeting software requirements instead of dealing with the shared functionality and more standard low-level details of providing a working system. A software framework’s purpose is to reduce overall development time.

With Pattern-Oriented Development the framework (a pattern pushed software framework) is the forerunner deliverable leading the rest of development. It is generally understood that the most effective software frameworks are those that evolve from refactoring the shared code of the enterprise. The software framework covered in this article certainly evolved this way – it was produced by developers for developers.

What the above tells you, is not to stop at design patterns but to take it a step further by adding the code for the design patterns by which time we label it as a [software] Framework – a Framework with Pattern-Oriented origins.

References to “Framework” in the rest of this article pertain to the pattern-oriented [software] frameworks as described in this section.

Object Discovery

Assume the task given to you is to service Apache helicopters and C-130 freighter planes. How will you go about this? First you break the work up for each to see what must be done to service them.

For the helicopter you have to:

· Resurface the rotor blades

· Do a bunch of other stuff

· Pump the tires

· Do a bunch of more things

For the C-130 you have to:

· Do some stuff

· Pump the tires

· Do some more stuff

From the above domain narrative, object discovery shows that we need a pump. We are good so far. But what commonly occurring problems did this examination exercise not show? Later in the article you will see real world examples of such.

Referenced Framework

The mentioned Framework applies to Web apps that run on over 100 device types including desktops, tablets and smartphones. The Framework examples shown in this article pertain specifically to Web-based applications. These Web applications were all developed with a mobile-first approach. in spite of of the screen size of the device, the Web applications developed, work equally well and renders well in spite of of the form factor of the device.

The mobile-first approach, just like the Web technologies being used in these apps, impacted the direction taken with this Framework.

Framework Observations

From the bits of the Framework exposed below, you will be able to tell that exception case handling was part of the solution right off the bat. Habitually developers truly write for the flawless conditions first. Why not? They get told, “We have to have this next Tuesday!” When they are done with “Tuesday’s” deliverable, they claim they are 90% done and they “only” need to add exception handling. Logging could be another deliverable in that remaining “10%” bucket.

Then the developers start adding the code for the exceptional situations, logging and so on. This results in the code having to be re-opened (violating the open-close principal). It also results in code paths that worked before, to be broken now and the system remains in a “90% done” state for a very, very long time.

Not meaning to deviate from the topic, but let me just mention that the developers take cover under the nimble methodology and call these next efforts, refactoring. There is a big difference between refactoring and building systems in a wrong and hurtful ordern.

Pattern-Oriented Development eliminates the mentioned issues – exception situations are handled right from the start, along with logging and more. Furthermore, these challenges are handled consistently across the application. The Framework takes care of the heavy lifting for the developers, thereby freeing them up so that they only need to focus on their domain.

What is very important to take observe of is that this Framework already covers the shared elements found in any Web application. That in itself is an excellent start for any Web app project.

Let’s look at a few examples of patterns found in the Web apps developed by the author.

Pattern: Server Side Generated User Messages

We have situations where at the server-end your code recognizes the need to show a message to the user. This could occur during a page request using any HTTP method (GET, POST, etc.) or during an AJAX (GET, POST, etc.) request. Developers should not have to be concerned with what the message boxes look like or how messaging should be implemented. There could have been a redirect between the time the message was turned over to the Framework and the time the user gets to see the message.

The developers shouldn’t have to concern themselves with such details. already if another message gets handed off to the Framework, be that in other places in the server-side code in the same HTTP request or the newly redirected to page, the user should be presented those messages. The Framework is responsible for making sure the user gets to see every message in a timely fact.

Is this one pattern or more? There is (1) the pattern telling the developers how to implement messaging or truly how to turn messaging over to the Framework instead of each developer rolling his/her own. Then, there is (2) the pattern dealing with the actual implementation details of messaging (not described here). Finally, (3) underneath the second pattern are patterns like the Proxy Pattern. The patterns mentioned in this article pertain to the Framework part plus a fleeting mention of the (usage) patterns presented to the application developers (as opposed to the Framework developers). The patterns geared towards the developers at large usually are and should be very simple patterns – simplicity rules!

Earlier in the aircraft servicing example, the article mentioned that not all shared problem areas get discovered from the problem/requirement narratives. When dealing with requirements or acceptance criteria such a messaging problem as seen here would possibly not be revealed and it would very easily be dealt with by a developer wherever it is needed in in any case way the developer sees fit at the time.

Pattern: Client Side Generated User Messages

The out-of-the-box Web technology methods window.alert() and window.confirm() without in functionality in addition as specialized user experience. Developers request the Framework to present messages to the user together with the button text and user options (for multiple selection message boxes), then leave the rest up to the Framework. At the end the developer code gets called back and told which option the user chosen (for multi selection message boxes).

Pattern: Web Forms and AJAX Post Backs

This pattern addresses the fact that when using ASP.NET WebForms and that performance is basic, not to use ASP.NET’s Update Panel for any AJAX work. Here the Framework takes care of the chief AJAX needs such as:

· Packaging up the form elements for post back.

· Make the AJAX call on behalf of the developer’s code.

· Assist at the server end with interpreting the received request and data.

· Deal with any exception handling and resultant user messaging including validation error handling.

Developer code only needs to request the Framework to perform the AJAX call and (only) implement the success code path.

Pattern: App Insights

App Insights is just a better term for what we usually call Help. Help is usually an on need kind Help, but you cannot clutter your UI everywhere with “information” icons either. The approach taken here is to show the user the App Insight when the user visits a given function of the system for the first time.

There, the user can temporarily or permanently dismiss the shown message. After permanently dismissing the message, the message will not be shown to the user again when he/she visits that particular functionality.

Developers simply need to ask the Framework to show a particular App Insight at the appropriate place in their code. The Framework knows to show the App Insight or not and will turn control back over to the developer code when done.

Pattern: Limit Work Unit to Single Tab per Browser example

When you cache data in the middle tier* (see appendix) the complication arises when a user opens the same work unit**(see appendix) in multiple tabs or windows in the same browser example. In the stateless HTTP world, the server cannot discriminate between the two tabs so as to continue each tab’s cache separately.

If it is justifiable, you can opt to not allow the same Work Unit from being opened multiple times in the same browser example. There are other alternatives like generating and sending tab identifiers to the server to be able to track the separate tabs’ cache, but stopping a user from opening the same Work Unit in more than one tab or window is the route we took with the applicable apps.

The developers just have to populate a hidden control (injected there via the mater page or shared view) with the appropriate Work Unit identifier.

Pattern: Prevent Post Back Hack Attempts

With the modern-day SPA application approach where the user views a list of entities and then identifies the entity the user wants to work with, there is the inclination to ship the entity’s identity column to the client.

When the user chosen task 8, the system made sure task 8 nevertheless exists and that the user gets the latest version of task 8. It then shows the above dialog to the user. When the user is done making the necessary changes, the dialog’s Update will send the task data to the server. The server now needs to know which task to update AND won’t be concerned with AJAX hack attempts.

Typically the developers tend to send the internal identifier of the entity (task 8 in this case) to the client/dialog. On update, the idea then is for the AJAX post back to echo the identity, and for the server side to use that identity to know which entity to update. This creates an opening for hackers to change the identity in the post back and try to update an entity the user does not have access to.

Additional security code (with a resource consumption and performance penalty of course) is then needed to detect and avoid such hack attempts. The Prevent Post Back Hack Attempts pattern provides an different to sending identities to the client and ensures that a hacker can only get to its own entities without the need for additional (expensive) security code and checks.

Pattern: Work Unit** Cache

For performance, security, and other reasons an application will remember given data for the work unit in the Middle Tier*. When a user jumps from one Work Unit to the next, the past Work Unit’s data should be removed from server cache. The only way to do that is to keep each Work Unit’s cache separate. Cache needs to get cleaned up at appropriate times or else server memory gets stressed which leads to performance problems.

Pattern: Cross Work Unit Cache

The cache shared across multiple Work Units should be cached in the Framework’s Cross Work Unit** Cache. Typically this cache will only get cleaned up after the user logs off. Developers will access the shared cache items from the Framework and not roll their own solutions.

Pattern: inner Integration

inner Integration involves particular return structures between the layers. Based on the content of the return structures, the developer code will know that a request was successful or not. In case of failure, the Framework takes over handling of the response.

These return types are there to adjust to the following challenges:

· Concurrency conflicts

· Updates with no changes made by the user

· Attempts to create a duplicate entity

· Validation

The above items are covered on their own later in the article where you will get better insights into what this is all about.

Pattern: Concurrency Conflicts

The approach taken here is the pessimistic locking approach — we want to know when an entity got updated since a user pulled a copy of it for update and inform the user of such at the time when the user tries to update the entity. The entity could also have been deleted in the meantime by another user.

This pattern describes to the developers how to detect and capture concurrency conflicts and how it is integrated into the Framework’s inner Integration.

Pattern: Update and No Changes

A user can hit the “Submit Changes” button when the user made no changes to the entity. Which tier should be used to perform this check and how should it be done? inner Integration is the meaningful to this pattern.

Pattern: Prevent Duplicate Entry

Logically it is the responsibility of the Business Rules inner to prevent a user from adding a duplicate entity into the system. Such a solution is a chatty and expensive solution, plus it leaves a small room for duplicate entry anyway. This pattern describes how duplicate entry attempt prevention is done. The Framework’s inner Integration plays a major role with this pattern.

Pattern: Logging

There are three types of logging:

· Exception

· Utilization

· Performance

Of course it is unnecessarily difficult to add logging after the fact. It should be part of the Framework from the start.

Pattern: Dropdown Controls

Dropdown controls need to be handled in a uniform fact in terms of:

· Empty lists

· Adding combo box capabilities

· Prompting the user to select an item

· Dealing with default selections.

Pattern: Adapt Validation Fields

When the system detects, at the client or sever end, invalid data in a form field, that field has to be styled as being in error. The pattern describes what the developers should do to get the advantage of the Framework’s adaptation of validation fields.

Pattern: Session Expiration

Your system relies on an active session, but if the user is idle after bringing up an entity for update in a dialog, then later returns and attempts to update the entity, the AJAX call arrives at the server end that does not have the session data any longer. There is no need for developers to code for session expiration during any kind of HTTP call. The Framework takes care of that already taking to the user the Login page if re-login is appropriate.

Pattern: Handling of Unsupported Browsers

Developers should be assured that by the time a browser reaches their pages, the browser is a supported browser. Leave the rest up to the Framework.

Pattern: Cookies Configuration

Checking to see if browser cookies are turned on or off should not be a developer task. It should solely be the responsibility of the Framework.

Pattern:…

The Framework has many more elements than mentioned so far. No Framework is complete without a complete set of extension methods and a number of other helper kind roles either. Examples of typical programming language types one would extend are URI, String and Date/Time.

This article is only aimed to touch on a few patterns and not to provide complete documentation on the complete Framework.

Reusability of the Framework

First be reminded that this Framework is specifically for Web based applications. The emphasis is also on development of Web Applications (interactive systems) instead of on development of “static” Web Sites.

Conceptually, with the Framework being a set of design patterns, it is applicable to any Web based software project. The server side code of this Framework is currently based on Microsoft’s technology stack. For different technologies, some of the Framework’s server-side code will have to be ported into the programming language of choice. However, being written in C#, it is not a complicated task. The UI side’s implementation of this Framework depends on jQuery.

There are other places in the code where the Framework relies on given capabilities, like that of the inner technology stack’s Object Relational Mapper, and such code will have to be rewritten for a different set of technologies.

Appendix A: Definition of Terms

Work Unit

The quickest way to explain a Work Unit is to look at a few examples of Work Units.

In a Project Management app one of the Work Units is the Project Work Unit. (This Project Work Unit follows the Single Page Application pattern) In this Work Unit the user starts off by being presented with a list of responsibilities under a particular project. The user can select a task and, via a dialog, modify the task. After modifying the task, the dialog closes and the user is back at the task list with the applicable task now containing the updates. The user can search for responsibilities, delete a task (via dialogs again), change the view of the list data, and much more. The Project Work Unit encompasses all these project related roles.

Similarly, in the same app, there is a Projects Work Unit where the user initially gets shown a list of projects. Again, the user can perform all kinds of project related roles while in the Projects Work Unit. These could be to add or modify projects, assign or remove users from a project, and more.

An example of a Wizard Pattern Work Unit is where you change to a different subscription package. From the first to the last page in this work flow consists of the Work Unit.

In looking at the Work Unit related patterns you will come to the realization why establishing Work Unit boundaries is very important.

Tiers and Layers*

The following Tiers and Layers:

UI Tier: Comprised of the UI inner running in the browser on a client machines.

Middle Tier: Comprised of the Business Façade, Business Rules and Data Access layers running on the Web/HTTP servers.

Database Tier: Comprised of the Database inner running on the database servers.

The following statement does not necessarily apply to a J2EE ecosystem but it does apply to a.NET ecosystem: More than one Tier can run on the same machine but Layers of the same Tier should not be spread out to run on different machines. (It is not the intent to explain the J2EE versus.NET statement as it involves.NET’s virtual processes, where the HTTP.SYS driver resides and more – a topic for another article).




leave your comment

Top