THE INTERPRETER PATTERN
Some programs benefit from having a language to describe
operations they can perform. The Interpreter pattern generally describes
defining a grammar for that language and using that grammar to interpret
statements in that language.
Motivation
When a program presents a number of different, but somewhat
similar cases it can deal with, it can be advantageous to use a simple language
to describe these cases and then have the program interpret that language.
Such cases can be as simple as the sort of Macro language recording facilities
a number of office suite programs provide, or as complex as Visual Basic for
Applications (VBA). VBA is not only included in Microsoft Office products,
but can be embedded in any number of third party products quite simply.
One of the problems we must deal with is how to recognize when a
language can be helpful. The Macro language recorder simply records menu
and keystroke operations for later playback and just barely qualifies as a
language; it may not actually have a written form or grammar. Languages
such as VBA, on the other hand, are quite complex, but are far beyond the
capabilities of the individual application developer. Further, embedding
commercial languages such as VBA, Java or SmallTalk usually require
substantial licensing fees, which make them less attractive to all but the
largest developers.
THE COMMAND PATTERN
The Chain of Responsibility forwards requests along a chain of
classes, but the Command pattern forwards a request only to a specific
module. It encloses a request for a specific action inside an object and gives it
a known public interface. It lets you give the client the ability to make
requests without knowing anything about the actual action that will be
performed, and allows you to change that action without affecting the client
program in any way.
Motivation
When you build a Java user interface, you provide menu items,
buttons, and checkboxes and so forth to allow the user to tell the program
what to do. When a user selects one of these controls, the program receives an
ActionEvent, which it must trap by subclassing, the actionPerformed event.
Let’s suppose we build a very simple program that allows you to select the
menu items File | Open and File | Exit, and click on a button marked Red
which turns the background of the window red. This program is shown
below.
CHAIN OF RESPONSIBILITY
The Chain of Responsibility pattern allows a number of classes to
attempt to handle a request, without any of them knowing about the
capabilities of the other classes. It provides a loose coupling between these
classes; the only common link is the request that is passed between them. The
request is passed along until one of the classes can handle it.
One example of such a chain pattern is a Help system, where every
screen region of an application invites you to seek help, but in which there are
window background areas where more generic help is the only suitable result.
When you select an area for help, that visual control forwards its ID or name
to the chain. Suppose you selected the “New” button. If the first module can
handle the New button, it displays the help message. If not, it forwards the
request to the next module. Eventually, the message is forwarded to an “All
buttons” class that can display a general message about how buttons work. If
there is no general button help, the message is forwarded to the general help
module that tells you how the system works in general. If that doesn’t exist,
the message is lost and no information is displayed. This is illustrated below.
Behavioral Patterns
Behavioral patterns are those patterns that are most specifically
concerned with communication between objects. In this chapter, we’ll see
that:
· The Observer pattern defines the way a number of classes can be notified
of a change,
· The Mediator defines how communication between classes can be
simplified by using another class to keep all classes from having to know
about each other.
· The Chain of Responsibility allows an even further decoupling between
classes, by passing a request between classes until it is recognized.
· The Template pattern provides an abstract definition of an algorithm, and
· The Interpreter provides a definition of how to include language elements
in a program.
· The Strategy pattern encapsulates an algorithm inside a class,
· The Visitor pattern adds function to a class,
· The State pattern provides a memory for a class’s instance variables.
· The Command pattern provides a simple way to separate execution of a
command from the interface environment that produced it, and
· The Iterator pattern formalizes the way we move through a list of data
within a class.
SUMMARY OF STRUCTURAL PATTERNS
In this chapter we have seen the
· The Adapter pattern, used to change the interface of one class to that of
another one.
· The Bridge pattern, intended to keep the interface to your client program
constant while allowing you to change the actual kind of class you
display or use. You can then change the interface and the underlying class
separately.
· The Composite pattern, a collection of objects, any one of which may be
either itself a Composite, or just a primitive object.
· The Decorator pattern, a class that surrounds a given class, adds new
capabilities to it, and passes all the unchanged methods to the underlying
class.
· The Façade pattern, which groups a complex object hierarchy and
provides a new, simpler interface to access those data.
· The Flyweight pattern, which provides a way to limit the proliferation of
small, similar class instances by moving some of the class data outside
the class and passing it in during various execution methods.
· The Proxy pattern, which provides a simple place-holder class for a more
complex class which is expensive to instantiate.
THE PROXY PATTERN
The Proxy pattern is used when you need to represent a complex
object by a simpler one. If creating an object is expensive in time or computer
resources, Proxy allows you to postpone this creation until you need the
actual object. A Proxy usually has the same methods as the object it
represents, and once the object is loaded, it passes on the method calls from
the Proxy to the actual object.
There are several cases where a Proxy can be useful:
1. If an object, such as a large image, takes a long time to load.
2. If the object is on a remote machine and loading it over the network may
be slow, especially during peak network load periods.
3. If the object has limited access rights, the proxy can validate the access
permissions for that user.
THE FLYWEIGHT PATTERN
There are cases in programming where it seems that you need to
generate a very large number of small class instances to represent data.
Sometimes you can greatly reduce the number of different classes that you
need to instantiate if you can recognize that the instances are fundamentally
the same except for a few parameters. If you can move those variables outside
the class instance and pass them in as part of a method call, the number of
separate instances can be greatly reduced.
The Flyweight design pattern provides an approach for handling such
classes. It refers to the instance’s intrinsic data that makes the instance
unique, and the extrinsic data which is passed in as arguments. The Flyweight
is appropriate for small, fine-grained classes like individual characters or
icons on the screen. For example, if you are drawing a series of icons on the
screen in a folder window, where each represents a person or data file, it does
not make sense to have an individual class instance for each of them that
remembers the person’s name and the icon’s screen position. Typically these
icons are one of a few similar images and the position where they are drawn
is calculated dynamically based on the window’s size in any case.
In another example in Design Patterns, each character in a font is
represented as a single instance of a character class, but the positions where
the characters are drawn on the screen are kept as external data so that there
needs to be only one instance of each character, rather than one for each
appearance of that character.
THE FAÇADE PATTERN
Frequently, as your programs evolve and develop, they grow in
complexity. In fact, for all the excitement about using design patterns, these
patterns sometimes generate so many classes that it is difficult to understand
the program’s flow. Furthermore, there may be a number of complicated
subsystems, each of which has its own complex interface.
The Façade pattern allows you to simplify this complexity by
providing a simplified interface to these subsystems. This simplification may
in some cases reduce the flexibility of the underlying classes, but usually
provides all the function needed for all but the most sophisticated users.
These users can still, of course, access the underlying classes and methods.
Fortunately, we don’t have to write a complex system to provide an
example of where a Facade can be useful. Java provides a set of classes that
connect to databases using an interface called JDBC. You can connect to any
database for which the manufacturer has provided a JDBC connection class —
almost every database on he market. Some databases have direct connections
using JDBC and a few allow connection to ODBC driver using the JDBCODBC
bridge class.
THE DECORATOR PATTERN
The Decorator pattern provides us with a way to modify the behavior
of individual objects without having to create a new derived class. Suppose
we have a program that uses eight objects, but three of them need an
additional feature. You could create a derived class for each of these objects,
and in many cases this would be a perfectly acceptable solution. However, if
each of these three objects require different modifications, this would mean
creating three derived classes. Further, if one of the classes has features of
both of the other classes, you begin to create a complexity that is both
confusing and unnecessary.
For example, suppose we wanted to draw a special border around
some of the buttons in a toolbar. If we created a new derived button class, this
means that all of the buttons in this new class would always have this same
new border, when this might not be our intent.
Instead, we create a Decorator class that decorates the buttons. Then
we derive any number of specific Decorators from the main Decorator class,
each of which performs a specific kind of decoration. In order to decorate a
button, the Decorator has to be an object derived from the visual
environment, so it can receive paint method calls and forward calls to other
useful graphic methods to the object that it is decorating. This is another case
where object containment is favored over object inheritance. The decorator is
a graphical object, but it contains the object it is decorating. It may intercept
some graphical method calls, perform some additional computation and may
pass them on to the underlying object it is decorating.
Introduction to C#
Introduction
C# is a Sharp C
C#, pronounced c sharp, is a computer language used to give instructions that tell the computer what to do, how to do it, and when to do it. This is a universal language that is used on many operating systems, including Microsoft Windows. C# is one of the languages used in the Microsoft .NET Framework. The Microsoft .NET Framework is a library of objects that create or draw things on the computer.
Recent Comments