First, we need to define a Design Pattern before we can work with them.Well, a Design Pattern (...affectionately called DP, or DeePee) can be defined as follows
A Design Pattern: is the naming and describing of abstract solutions across a range of recurring design problems
A Pattern can be defined as: A Model that can be imitated. Hence a Design pattern is a Model that can be imitated to solve similar design problems.
A Pattern is not: meant to facilitate inheritance. Inheritance is Design-time flexibility. Design Patterns provide run-time flexibility and solve problems of object role and interactions.
A typical example of a design pattern used repeatedly in Enterprise DNA solutions we have implemented is the Stateless Object. later in this class, we will look at the internals of such a stateless object written in Visual Basic,which will help clarify some of these theoretical points.
· A Stateless object is loosely coupled.
· A Stateless object has no attributes, only methods
· A Stateless object is typically used in a create-as-needed/destroy-when-done programming model.
· A Stateless object meets the needs for scalability and flexibility that are the primary requirments for a middle-tier in a Web application.
The best way to understand a Stateless Object model is to compare and contrast it with a typical Stateful Object model common to client-server applications everywhere.
An example of a Stateful Object model is shown below. This simple example models the family dynamic centered around a parent/child/car.
Note the following important points in this design
· All Objects are tightly coupled to each other
· Parent & Child definitions inherit from a generic 'Person' definition, as does the 'Car' from 'Vehicle'.
· Objects instantiated using this model will have the capability of maintaining "State".
o This means we caan set attributes of a Child and be able to retrieve attributes of it's child, or even the car whose owner is the parent, etc...
The disadvantages of this design in a Web environment are as follows:
· In order to create a 'state' using this model, every attribute of the objects in play needs to be manipulated by the application. This means one network trip per attribute. This destroys any scalability hopes we might hope for.
· The interfaces are tightly coupled at design time, which means that when the objects are deployed they are stuck with each other.
o So, if the Car object is accessed more frequently, we cannot move it to another piece of hardware to improve performance, we have to move the entire family of related objects...
· Extra overhead through inheritance... even though inheritance promotes good OO practices such as code-reuse, at run-time, creating an object from a concrete class (e.g. Car) leads to additional overhead due to the presence of an abstract parent class ('Vehicle')
Redesigning the above Stateful model will give us something that looks like this
Notice the key differences between this model and the earlier one
· It's uglier !
· Objects are de-coupled from each other. There is no obvious relationship between a person and a car. There is, in fact, no need to create one explicitly.
o Let's say, as part of a application, we need to model the following process: "User buys car". To do this, we simplly instantiate a Person object, and invoke the BuyCar method and give the BuyCar method EVERY scrap of information it needs to model buying a car. Doing so lets us use the create/destroy model we talked about earlier.
o Since objects are de-coupled, we cannot use inheritance
· We have to write more code, since each method must be told everything it needs to know about a person in the context of its invocation
· Allows us to deploy frequently used objects to their own hardware... INSTANT SCALABILITY..!
· Overhead of method invocation is often lower, because no State information is required to be maintained
Performance and Scalability are the therefore GODS of Web-based application design.
The success of the Middle-tier depends on it's ability to scale easily with number of concurrent users, and it's ability to provide a consistent level of performance throughout the process of scaling.