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: 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 Object Oriented Programming; Design Patterns;

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) { } } catch(Exception e) { thrownewException(e.ToString()); } returninstance; InitDB();

} } }

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 ReusableOriented Software. (1994). pp. 11. [4] GAMMA, Erich et. al. Design Patterns: Elements of ReusableOriented Software. (1994). pp. 12. [5] FOWLER, M. Anemic Domain Model. (2003) [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) [8] MAIORIELLO, J. Applying Design Patterns to Solve Design Issues (2003) [15] GAMMA, Erich et. al. Design Patterns: Elements of ReusableOriented Software. (1994). pp. 96. [11] EVANS, E. Domain-driven design: tackling complexity in the heart of software. (2004). pp. 3. [12] EVANS, E. Domain-driven design: tackling complexity in the heart of software. (2004). pp. 3. [13] EVANS, E. Domain-driven design: tackling complexity in the heart of software. (2004). pp. 24.