APPROACHES TO SOFTWARE DESIGN
APPROACHES TO SOFTWARE DESIGN
There are two fundamentally different approaches to software design that are in use today function-oriented design, and object-oriented design.
Though these two design approaches are radically different, they are complementary rather than competing techniques.
The object oriented approach is a relatively newer technology and is still evolving.
For development of large programs, the object- oriented approach is becoming increasingly popular due to certain advantages that it offers.
On the other hand, function-oriented designing is a mature technology and has a large following.
The following are the salient features of the function-oriented design approach:
In top-down decomposition, starting at a high-level view of the system, each high-level function is successively refined into more detailed functions.
For example, consider a function create-new-library member which essentially creates the record for a new member, assigns a unique membership number to him, and prints a bill towards his membership charge.
This high-level function may be refined into the following subfunctions:
Each of these sub functions may be split into more detailed subfunctions and so on.
Centralised system state:
The system state can be defined as the values of certain data items that determine the response of the system to a user action or external event.
For example, the set of books (i.e. whether borrowed by different users or available for issue) determines the state of a library automation system.
Such data in procedural programs usually have global scope and are shared by many modules.
The system state is centralised and shared among different functions.
For example, in the library management system, several functions such as the following share data such as member-records for reference and updation:
A large number of function-oriented design approaches have been proposed in the past.
A few of the well-established function-oriented design approaches are as following:
• Structured design by Constantine and Yourdon, 
• Jackson’s structured design by Jackson 
• Warnier-Orr methodology [1977, 1981]
• Step-wise refinement by Wirth 
• Hatley and Pirbhai’s Methodology 
In the object-oriented design (OOD) approach, a system is viewed as being made up of a collection of objects (i.e. entities).
Each object is associated with a set of functions that are called its methods.
Each object contains its own data and is responsible for managing it.
The data internal to an object cannot be accessed directly by other objects and only through invocation of the methods of the object.
The system state is decentralised since there is no globally shared data in the system and data is stored in each object.
For example, in a library automation software, each library member may be a separate object with its own data and functions to operate on the stored data.
The methods defined for one object cannot directly refer to or change the data of other objects.
The object-oriented design paradigm makes extensive use of the principles of abstraction and decomposition as explained below.
Objects decompose a system into functionally independent modules.
Objects can also be considered as instances of abstract data types (ADTs).
The ADT concept did not originate from the object-oriented approach. In fact, ADT concept was extensively used in the ADA programming language introduced in the 1970s.
ADT is an important concept that forms an important pillar of object orientation.
Let us now discuss the important concepts behind an ADT. There are, in fact, three important concepts associated with an ADT
—data abstraction, data structure, data type.
The principle of data abstraction implies that how data is exactly stored is abstracted away. This means that any entity external to the object (that is, an instance of an ADT) would have no knowledge about how data is exactly stored, organised, and manipulated inside the object.
The entities external to the object can access the data internal to an object only by calling certain well-defined methods supported by the object.
Consider an ADT such as a stack. The data of a stack object may internally be stored in an array, a linearly linked list, or a bidirectional linked list.
The external entities have no knowledge of this and can access data of a stack object only through the supported operations such as push and pop.
A data structure is constructed from a collection of primitive data items.
Just as a civil engineer builds a large civil engineering structure using primitive building materials such as bricks, iron rods, and cement; a programmer can construct a data structure as an organised collection of primitive data items such as integer, floating point numbers, characters, etc.
A type is a programming language terminology that refers to anything that can be instantiated.
For example, int, float, char etc., are the basic data types supported by C programming language.
Thus, we can say that ADTs are user defined data types. In object-orientation, classes are ADTs.
Advantages of using ADTs in programs:
The data of objects are encapsulated within the methods. The encapsulation principle is also known as data hiding.
The encapsulation principle requires that data can be accessed and manipulated only through the methods supported by the object and not directly.
This localises the errors. The reason for this is as follows. No program element is allowed to change a data, except through invocation of one of the methods. So, any error can easily be traced to the code segment changing the value. That is, the method that changes a data item, making it erroneous can be easily identified.
An ADT-based design displays high cohesion and low coupling. Therefore, object- oriented designs are highly modular.
Since the principle of abstraction is used, it makes the design solution easily understandable and helps to manage complexity. Similar objects constitute a class. In other words, each object is a member of some class. Classes may inherit features from a super class. Conceptually, objects communicate by message passing. Objects have their own internal data. Thus an object may exist in different states depending the values of the internal data. In different states, an object may behave differently.
Object-oriented versus function-oriented approaches design
Unlike function-oriented design methods in OOD, the basic abstraction is not the services available to the users of the system such as issuebook, display-book-details, find-issued-books, etc., but real-world entities such as member, book, book-register, etc.
For example in OOD, an employee pay-roll software is not developed by designing functions such as update-employee-record, get-employee-address, etc., but by designing objects such as employees, departments, etc.
In OOD, state information exists in the form of data distributed among several objects of the system. In contrast, in a procedural design, the state information is available in a centralised shared data store.
For example, while developing an employee pay-roll system, the employee data such as the names of the employees, their code numbers, basic salaries, etc., are usually implemented as global data in a traditional programming system; whereas in an object-oriented design, these data are distributed among different employee objects of the system. Objects communicate by message passing. Therefore, one object may discover the state information of another object by sending a message to it. Of course, somewhere or other the real-world functions must be implemented. Function-oriented techniques group functions together if, as a group, they constitute a higher level function. On the other hand, objectoriented techniques group functions together on the basis of the data they operate on.
To illustrate the differences between the object-oriented and the functionoriented design approaches, let us consider an example—that of an automated fire-alarm system for a large building. Automated fire-alarm system—customer requirements
The owner of a large multi-storied building wants to have a computerised fire alarm system designed, developed, and installed in his building. Smoke detectors and fire alarms would be placed in each room of the building.
The fire alarm system would monitor the status of these smoke detectors. Whenever a fire condition is reported by any of the smoke detectors, the fire alarm system should determine the location at which the fire has been sensed and then sound the alarms
only in the neighbouring locations.
The fire alarm system should also flash an alarm message on the computer console. Fire fighting personnel would man the console round the clock. After a fire condition has been successfully handled, the fire alarm system should support resetting the alarms by the fire fighting personnel. Function-oriented approach: In this approach, the different high-level functions are first identified, and then the data structures are designed. The functions which operate on the system state are: interrogate_detectors(); get_detector_location(); determine_neighbour_alarm(); determine_neighbour_sprinkler(); ring_alarm(); activate_sprinkler(); reset_alarm(); reset_sprinkler(); report_fire_location(); Object-oriented approach: In the object-oriented approach, the different classes of objects are identified. Subsequently, the methods and data for each object are identified. Finally, an appropriate number of instances of each class is created. class detector attributes: status, location, neighbours operations: create, sense-status, get-location, find-neighbours class alarm attributes: location, status operations: create, ring-alarm, get_location, resetalarm class sprinkler attributes: location, status operations: create, activate-sprinkler, get_location, reset-sprinkler We can now compare the function-oriented and the object-oriented approaches based on the two examples discussed above, and easily observe the following main differences: In a function-oriented program, the system state (data) is centralised and several functions access and modify this central data. In case of an object-oriented program, the state information (data) is distributed among various objects. In the object-oriented design, data is private in different objects and these are not available to the other objects for direct access and modification. The basic unit of designing an object-oriented program is objects, whereas it is functions and modules in procedural designing. Objects appear as nouns in the problem description; whereas functions appear as verbs. At this point, we must emphasise that it is not necessary that an objectoriented design be implemented by using an object-oriented language only. However, an object-oriented language such as C++ and Java support the definition of all the basic mechanisms of class, inheritance, objects, methods, etc. and also support all key object-oriented concepts that we have just discussed. Thus, an object-oriented language facilitates the implementation of an OOD.
However, an OOD can as well be implemented using a conventional procedural languages—though it may require more effort to implement an OOD using a procedural language as compared to the effort required for implementing the same design using an object-oriented language. In fact, the older C++ compilers were essentially pre-processors that translated C++ code into C code. Even though object-oriented and function-oriented techniques are remarkably different approaches to software design, yet one does not replace the other; but they complement each other in some sense.
For example, usually one applies the top-down function oriented techniques to design the internal methods of a class, once the classes are identified.
In this case, though outwardly the system appears to have been developed in an object-oriented fashion, but inside each class there may be a small hierarchy of functions designed in a top-down manner.