100% found this document useful (1 vote)
405 views

Design Patterns SW Quality - English Version

As a high demand activity, the software development using object oriented technologies has been adopted by reuse benefits, maintainability facility and architecture quality. This paper studies some design patterns as a solution for common software development and design problems
Copyright
© © All Rights Reserved
Available Formats
Download as RTF, PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
405 views

Design Patterns SW Quality - English Version

As a high demand activity, the software development using object oriented technologies has been adopted by reuse benefits, maintainability facility and architecture quality. This paper studies some design patterns as a solution for common software development and design problems
Copyright
© © All Rights Reserved
Available Formats
Download as RTF, PDF, TXT or read online on Scribd
You are on page 1/ 18

Improving object oriented software

quality using design patterns and


modern software engineering
methodologies
Ademir Constantino Filho
{ ademirconstantino .at. gmail.com }
Constantino IT – http://www.constantinoit.com.br/
06/20/2010

Abstract: As a high demand activity, the


software development using object oriented
technologies has been adopted by reuse
benefits, maintainability facility and architecture
quality. This paper studies some design patterns
as a solution for common software development
and design problems.

Keywords: Object Oriented Programming; Design Patterns;


Software Quality.

INTRODUCTION

The software development production grows every year year the


way as the large, medium and small corporations decide to automate its
process looking for business improvement and cost reduction.

In spite of developed software attend business requirements, in


the most cases the maintenance becomes inevitable, considering that
many process in the company can change by new laws, a quality
process or a new functional requirement.

Software maintenance accounts for more effort than any other


software engineering activity. Maintainability is the ease with which a
program can be corrected if an error is encountered, adapted if its
environment changes, or enhanced if the customer desires a change in
requirements. There is no way to measure maintainability directly;
therefore, we must use indirect measures. [1]

If we consider the software development process, where software


development methodologies are applied looking for the process
excellence with software engineering, there is no way to estimate the
software maintenance phase, but it can be used one simple metric to
program the change, test it and distribute for all the users [2]. This
phase normally takes the largest time of the project because changes
and fixes are always requested by the clients. We have to consider that
the architecture quality in the development and the software
engineering process defined helps the maintainability phase, the
software quality being achieved by using documented solutions to
reduce duplicated code and for the changes generated on demand being
executed maintaining the project quality and allowing the future
implementations be done without strong effort.

One bad projected system normally needs much more code to do


the same things many times because the same code was duplicated in
many different places. As much difficult to see the project by the code,
more difficult it will be to preserve this code and it will be totally
destructured. The elimination of duplicated code is a important aspect to
improve the project, considering that reducing the code quantity makes
a big difference in the software maintenance.

One thing expert designers know not to do is solve every problem


from first principles. Rather, they reuse solutions that have worked for
them in the past. When they find a good solution, they use it again and
again. The design patterns introduced by the Gang of Four are widely
known by designers, architects and experienced developers whom apply
it on the resolution of architecture problems making it possible be
modified and to attend future requirements on their projects. [3]

The following topics will introduce the design patterns introduced


by the computer scientist team known as Gang of Four, formed by four
members: Erich Gamma, Richard Heml, Ralph Johnson, John Vlissides,
authors of the book “Design Patterns: Elements of Reusable Software”
focusing on software development quality.

DESIGN PATTERNS

The design pattern concept was created by the architect


Cristopher Alexander in 1977, where he defined "Each pattern describes
a problem which occurs over and over again in our environment, and
then describes the core of the solution to that problem, in such a way
that you can use this solution a million times over, without ever doing it
the same way twice [4]”, being afterward introduced to the computer
science in the OOPSLA-1987 by the computer programmers Kent Beck e
Ward Cunningham, where they presented five small design patterns to
create windows using the object oriented language Smalltalk.

In general the design patterns can be classified in three different types:

• Creational patterns: Abstract all the object creation by the


instantiation of classes.

• Structural patterns: Threat the way objects and classes are


organized to create greater structures.

• Behavioral patterns: Involves algorithms and responsibility


attribution.
The design patterns became widely known with the popularity of
C++ and afterward Java, Ruby and dot net technologies. Normally
design patterns are applied to improve software quality, reuse benefits
and cost reduction forms.

Considering that design patterns allow designs solutions, in the


next pages object design problems will be discussed and some design
patterns solutions applied for educational purposes only.

3. COMMOM ARCHITECTURE PROBLEMS

• Database Connection Service:

Considering one case where a object establish the connection to


the DBMS, normally one method starts it and so transactions and queries
can be executed. One simplest solution here would be connect to the
database, execute the commands and close the connection after
completed, displaying the results on the user screen.

Consider this connection doesn't need to be closed until the


master thread (the program) be finished, because if the program has
one open connection, this one could be used obtaining the maximum
network throughput, reducing the network overhead or possible
connection limitations by the database. This problem could be easy
solved by using one design pattern that allows just one connection to
the database, making it available anywhere the program requests it.

• Domain Driven Design:

One academic study group developing one small project had to


create one domain where one Person can send Messages and the
messages would be represented by its own classes. Basically after
created the domain the message implementation became necessary, so
the group created one class to encapsulate the business logic for the
message called PersonService.

The following code shows a Ruby implementation for this


case:

classPersonType
NATURAL=1;
JURIDICAL=2;
end

classPerson

@personName;
@personType;
@messageList;

definitialize(personType)
@personType=personType;
end

# getters and setters

end

classMessage

@menssageData;

# getters and setters

end

classPersonService

@person;

definitialize(person)
@person=person;
end

defsendMessage(mess)
# message sending implementation
end

end
Tabela 1. Source Code for an Anemic Domain

The basic symptom of an Anemic Domain Model is that at first


blush it looks like the real thing. There are objects, many named after
the nouns in the domain space, and these objects are connected with
the rich relationships and structure that true domain models have. The
catch comes when you look at the behavior, and you realize that there is
hardly any behavior on these objects, making them little more than bags
of getters and setters. Indeed often these models come with design rules
that say that you are not to put any domain logic in the domain objects.
Instead there are a set of service objects which capture all the domain
logic. These services live on top of the domain model and use the
domain model for data. [5]

The key difference between procedural and object oriented


programming, in object oriented design, attributes and behavior and
contained within a single object, whereas in procedural, or structured
design the attributes and behavior are normally separated. [6]

So here, it can be identified not just a need of applying one design


pattern, but a bad practice that have been occurring in the long of the
years.

• Redundant code elimination when applied the abstraction


principle (coding to the interface).

A common change in software is the domain model. Consider one


case where one tracking company wants to track its vehicles (trucks) in
trip. In this system a batch scheduler for process that runs from 2 to two
minutes.
All the process are called Alert, when one truck is out of route the
process is identified by the Alert called Out of Route, in the situation to
one not allowed the Alert is called AlertNotAllowedBreak, but it can have
many kinds of different alerts.

The system designers defined the following model:

Diagram 1. Pseudo UML diagram to represent the the simple


Alert domain model.

The abstraction allows the developer to separate an object's


implementation from its behavior. This separation creates a "black-box"
affect where the user is isolated from implementation changes. As long
as the interface remains the same, any change to the internal
implementation is transparent to the user. [7]

The point here is in the condition of many kind of Alerts to be


created .The current system has a class that schedule all the batch
process, considering that in the future it will exist much more classes
making use of these objects and when you work with abstract objects its
common to instantiate concrete objects based on system conditions.
Consider the following code:
Public Map<Vehicle, Alert>
listAlertsByVechicle(Collection<Vehicle>vehicleList) {

Map<Vehicle, Alert>executionAlert = newHashMap<Vehicle, Alert>();


for(VehicleactualVehicle: vechicleList) {

if(actualVehicle.isMonitored()) {
for(TrackingSystemservice:
actualVehicle.getAvailableServices()) {

switch(service) {

case OUT_OF_ROUTE:

Alert serviceAlert =
newAlertOutOfRoute();
executionAlert.put(atualVehicle,
serviceAlert);
break;

case NOT_ALLOWED_BREAK:

Alerta serviceAlert =
newAlertNotAllowedBreak();
executionAlert.put(actualVehicle,
serviceAlert);
break;

default:
break;

}
}

}
Table 2. Source code used to program to the interface

The code above shows that beyond creating the necessary Alerts
for the vehicles with available services, it returns Alerts contained in one
List to be afterward executed by another thread. Consider the situation
that many parts of the system make use of the Alerts, and despite of it
looks not so probably in the beginning of the project, one future
requirement may need the same code impacting in a negative
duplicated code.
4. SOLUTION PROPOSAL TO THE FOLLOWING DESIGN PROBLEMS

Since the beginning, software has been created to solve specific


problems. The more software architects has a clearly understanding of
the requirements, the system can be created to attend users needs and
requirements. Since the systems are in use and in the users hand, the
sucess systems has to support and attend requirements changes. [8]

Design patterns describe solutions. Solutions that we know to work


“positively” in specific problems. The solutions are documented as a
pattern and all the aspects are described, even the details of the
implementation if they help and be relevant. [8]

According in the 3 basic principles of the object oriented paradigm,


fundamental objectives bases in three basic strategies to create good
object oriented architectures. They are:

• Program to the interface;


• Prefer composition to inheritance;
• Identify and encapsulate what changes.

So we can see the object oriented principles and the design


patterns work together when you use a good architecture. Some design
patterns can combine or conduce one to another, and also can be
similar, alternative, conduce to other or be alternative. There is no right
solution for design pattern or problem solution. Some solutions are
proposed in the items to the following application exemplification or
applied patterns, in spite of not being the only solution for the design
problems or oriented object software.

• Singleton pattern for DBMS access.


To create a functional class that provides the same connection to
the application, it would be necessary to provide the connection to the
application when needed, but it would first be used as a pattern called
singleton, categorized as a creational pattern by the Gang of Four as:

It's important for some classes to have exactly one instance.


Although there can be many printers in a system, there should be
only one printer spooler. There should be only one file system and
one window manager. A digital filter will have one A/D converter.
An accounting system will be dedicated to serving one company.
[9]

A applicability of a singleton is defined by the Gang of Four as


“there must be exactly one instance of a class, and it must be accessible
to clients from a well-known access point”. [10]

The image bellow shows one service object that applies the
singleton pattern:

Figure 2. Diagram that exemplifies a singleton service

The C# code bellow shows the coded example for this problem:
Public classConnectionService{

privateConnectionService instance;
privateDbConnection connection;

privateConnectionService() {

this.InitDB();

Public static synchronized ConnectionService Instance {


get
{
try{

if(instance == null)
{
instance = newConnectionService();
}

else
{

if(instance.conexao.ConnectionState
== ConnectionState.Closed)
{
InitDB();
}

}
catch(Exception e) {
thrownewException(e.ToString());
}
returninstance;
}

privatevoidInitDB() {
// establish database connection
}

}
Table 3. Source code with the singleton implementation

The exemplified class above ConnectionService can be used as the


code bellow:
Public class PersonDAO {

privateDbConnection connection;

publicList<Person>RecuperaListaPessoas() {

List<Person>clRetorno = newList<NaturalPerson>();

connection = ConnectionService.Instance;
DbCommand command = connection.CreateCommand();
command.CommandText = "SELECT * FROM Person";

DbDataReader reader = connection.ExecuteReader();

while(reader.Read())
{

Person p = newNaturalPerson();
p.setId(rs.getInt("id"));
p.setName(rs.getString("name"));

clRetorno.add(p);

returnclRetorno;

Table 4. Source code using to the singleton pattern service

The code bellow shows the use of the unique connection and
centralized when necessary, the benefit and facility of use, brings
benefits of reuse and network and system performance.

The synchronized modifier in used the getInstance method, so the


connection service is used in a synchronized mode, reducing concurrent
problems, but we need to be aware that this solution is not viable in web
systems, because just one connection to the DBMS will be available for a
big quantity of users. The basic Java Database Connectivity (JDBC) 2.0
has classes that applies the connection pool concept and can be used in
centralized or concurrent systems.

• Domain driven design


Software modeling and code has been walking together in the
process of software development, in spite of it doesn't reflect the same
meaning when generated the final artifacts.

The domain-driven-design is bunch of principles that helps in the


software development when it is oriented to the domain; it is the process
that exists in the real world and not ignoring the fact that the domain is
expressed in the code.

Looking to the integration between domain design and coding ,


Erich Evans introduced in 2004 the book titled as “Domain Driven
Design – Tackling complexity in The Heart of The Software”, where he
defines many software engineering techniques including direction to the
development process and to the software architecture.

To create software that is valuably involved in the user’s activities,


a development team must bring to bear a body of knowledge related to
those activities [11]

A simple’s example would be an accounting software project,


where the development team using requirement meetings and other
communication forms has to understand and bring this knowledge to the
project.

The domain model is not a particular diagram; it is the idea that


the diagram is intended to convey. It not just the knowledge in a domain
experts head; it is rigorously organized and selective abstraction of that
knowledge. A diagram can represent and communicate a model as can
carefully written code as can a English sentence. [12]
The stakeholders in the project can be classified as the specialist
team (domain experts) considering the previous example the
accountants that have to understand the technical part to help in the
artifact generation and the technical team (software developers) that
needs to have the complete domain of the technologies and also
understand the domain.

The model doesn't need to be a source code or a UML diagram, it


can be a requirement specification sketch, meeting annotations or any
other form to represent knowledge.

Domain experts have limited understanding of the technical jargon


of the software development, but hey use jargon of their field – probably
in various flavors. Developers, on the other hand, may understand and
discuss the system in descriptive, functional terms, devoid of meaning
carried by the expert’s language. [13]

The main problem here is that the software developers doesn't


understand many jargons and terms used by the specialists, creating
their own definitions in the software artifacts (in the diagrams and in the
code), creating distinct languages from the domain specialists and these
different languages makes the software artifacts be disconnected from
the business reality.

The two teams will help to achieve a quality domain model with
many meetings, informal conversations and knowledge transfer, in both
sides. But it is not any conversation that is useful. The useful
conversation is the one that the result becomes integrated to the code,
with no intermediates. Terms used by the teams has to be widely
accepted, used and understood as the language the two teams has to be
the same.
To define a common language to the both teams, Evans defined as
the ubiquitous language the terms that has to be applied in classes,
operations, attributes and all the software artifacts. This language
includes terms to discuss rules that have been defined in the domain
model.

In the previously example, where one person send messages as


the business, the Person class could encapsulate the send message
operation, because Person is the one who send messages and it would
be necessary and would make a positive cascade effect because it would
be necessary to define other layers in the project.

•Redundant code elimination when applied to abstraction


principle.

When used the interface programming or the abstraction principle


as the Figure 1 and Table 2 shows, some attention is necessary to the
changes that can occur in the system, because the interface defines the
behavior without knowing what kind of objects will be used and to this
exists a pattern that can help in the creation of common object types.

As discussed before, the system has to be prepared to attend


future requirements, in other words, it has to support new types of Alerts
without being necessary a big change in the system.

By coding to an interface, you know you can insulate yourself from


a lot of changes that might happen to a system down the road. Why? If
your code is written to an interface then it will work with any new
classes implementing that interface though polymorphism. However
when you have code that makes use of many concrete classes, you're
looking for trouble because that code may have to be changed as new
concrete classes are added. So, in other words, your code will not be
“closed for modification”. To extend it with new concrete types, you'll
have to reopen it. [14]

The problem with the previous code in the Table 2,


listAlertsByVechicle(Collection<Vehicle> vehicleList), that returns the
available Alerts to the specific vehicles passed as parameter, all the
situations involving the alerts creation would be duplicated, impacting in
a difficult project maintenance.

In cases to the Alert Objects be created by the available services,


it would be possible to create a method using the Abstract Factory
pattern, a creational pattern defined by the gang of four with the
following intention:

Provide an interface for creating families of related or dependent


objects without specifying their concrete classes. [15]

One solution in this case would be create a class called


AlertFactory, responsible for creating Alerts using the method
createAlert(TrackingSystem service), where the tracking service can be
used as a parameter to identify the object type to be created, making it
easier and all the creational process centralized in this object making
also possible that the creational part being used in just one class.

The code bellow shows a simple solution to the case exemplified


before:
Public class AlertFactory {

publicAlertacreateAlert(TrackingServiceservice) {

Alert returnAlert = Alert.NULL_ALERT;

switch(service) {

caseOUT_OF_ROUTE:

returnAlert = newAlertOutOfRoute();
break;

caseNOT_ALLOWED_BREAK:

returnAlert = newAlertNotAllowedBreak();
break;

default:
break;

returnreturnAlert;
}

Table 5. Source code exemplified the Abstract Factory pattern.

5. CONCLUSION

The use of design patterns becomes necessary when applied the


object oriented paradigm to program APIs, frameworks and also final
projects using benefits of reuse and architectural quality. As a trivial
knowledge of architects, designers and software developers, the design
patterns already documented creates a knowledge base that if applied
since the project begin guarantee efficiency and efficacy in the
maintenance phase and quality in the development perspective.

One simple definition to design pattern is just knowledge from


experienced developers to solve object oriented software design
problems.
The use of design patterns allowed reuse solutions based to other
systems be developed allowing best productive results and popular
languages like Java, Ruby and C#, based in the object oriented
paradigm, make use of modern techniques like design patterns to
develop high quality software.

REFERENCES

[1] PRESSMAN, R. S. Software Engineering: a practitioner's approach. [9] GAMMA, Erich et. al. Design Patterns: Elements of Reusable-
(2004). pp. 96-97. Oriented Software. (1994). pp. 130.

[2] PRESSMAN, R. S. Software Engineering: a practitioner's approach. [10] GAMMA, Erich et. al. Design Patterns: Elements of Reusable-
(2004). pp. 97. Oriented Software. (1994). pp. 130.

[3] GAMMA, Erich et. al. Design Patterns: Elements of Reusable- [11] EVANS, E. Domain-driven design: tackling complexity in the heart
Oriented Software. (1994). pp. 11. of software. (2004). pp. 3.

[4] GAMMA, Erich et. al. Design Patterns: Elements of Reusable- [12] EVANS, E. Domain-driven design: tackling complexity in the heart
Oriented Software. (1994). pp. 12. of software. (2004). pp. 3.

[5] FOWLER, M. Anemic Domain Model. (2003) [13] EVANS, E. Domain-driven design: tackling complexity in the heart
of software. (2004). pp. 24.
[6] WEISFIELD, M. A. The object-oriented thought process. (2004)
[14] FREEMAN, E; Heard First: Design Patterns. (2004) pp. 111.
[7] KHOR, K-K. IBM Smalltalk Tutorial. (1995)
[15] GAMMA, Erich et. al. Design Patterns: Elements of Reusable-
[8] MAIORIELLO, J. Applying Design Patterns to Solve Design Issues Oriented Software. (1994). pp. 96.
(2003)

You might also like