What is software reusability

Programming principles

This article meets the GlossarWiki quality requirementsonly partially:

correctness: 5
(fully checked)
scope: 4
(unimportant facts are missing)
References: 2
(important sources are missing)
Source types: 3
(Well)
conformity: 5
(excellent)

annotation: In this article the two arrows "→" and "⇒" have the following meanings:

⇒: "has the consequence"
→: "contributes to", "improves", "increases"
  • 1. Purpose
  • 2goals
  • 3Software properties to meet the two objectives
  • 4 programming principles
    • 4.1 Understandability, comprehensibility, legibility, readability
    • 4.2 Writability
    • 4.3 Steadiness, continuity
    • 4.4 Configurability, Customizability
    • 4.5 Don't repeat yourself, DRY[1]
    • 4.6 Repeat yourself, RY[2]
    • 4.7 Demeter Law[3], Law of Demeter, LoD
    • 4.8 Verifiability, verifiability
    • 4.9 Make use of interfaces
    • 4.10 Use integrity constraints, Make Use of Integrity Constraints, Design by Contract[4]
    • 4.11 Liskov's principle of substitution[5], LSP, substitution principle, Liskov substitution principle[6]
    • 4.12Modularity, modularity, divide and rule, divide et impera
      • 4.12.1Five requirements from Bertrand Meyer
      • 4.12.2Bertrand Meyer's six principles
      • 4.12.3 Further module principles
  • 5Sources
  • 6See also

1. Purpose

In order to be able to create useful, yet inexpensive programs and applications, one should observe a number of programming principles.

Before the programming principles can be described in more detail, the goals that are to be achieved with these principles are first specified in more detail.

2 goals

The aim of every software development project should be the creation of software that has two properties:

useful
The software should be useful to the user.
inexpensive
The software should generate as low costs and follow-up costs as possible.

3 software properties to meet the two objectives

In order to achieve the two aforementioned goals, a software package should have the following properties:

specified
In order to be able to assess the usefulness and correctness of the software package before it is used, a specification should be available that describes the tasks and properties of the package in detail.
⇒ usefulness (can be estimated)
correct
The implementation of the package should be correct, so it should meet the specification in all points.
⇒ Usefulness: A software that does not work correctly is of no use to the user in the faulty situations.
⇒ no costs due to wrong or unexpected behavior
robust (robust)
The software package should run stably even in abnormal (unspecified) situations.
⇒ no costs due to inconsistencies
⇒ low costs for operating errors and system failures
usable
The software package should be easy to learn and use.
⇒ Usefulness is improved
⇒ low training costs
⇒ Incorrect use rarely occurs and therefore rarely results in costs
⇒ no costs from frustrated users
secure
Unauthorized access to data or programs should be impossible.
⇒ no costs due to security deficiencies
efficient
The software package should have the best possible runtime and storage efficiency, i.e. use the available resources as well as possible.
⇒ low personnel costs due to short waiting times
⇒ low costs due to low hardware requirements
maintainable
The software package should be easy to adapt to new circumstances. Errors should be easy to fix (since they can never be completely avoided).
⇒ low maintenance costs

There are three special cases for the property "maintainable", which should be mentioned separately here:

compatible
The software package should be compatible with existing systems, i.e. it should support standardized interfaces.
⇒ low integration and adaptation costs
portable
The software package should be easy to port to new systems.
⇒ low costs when changing the runtime environment
extensible
It should be possible to implement extensions to the specification quickly.
⇒ low maintenance costs

4 programming principles

In order to achieve the aforementioned goals, the following programming principles should be observed:

4.1 Understandability, comprehensibility, legibility, readability

Write code that is readable and understandable.
The program code should be as easy to read and understand as possible. This means that the code should be properly formatted, descriptive identifiers should be used, meaningful comments should be inserted etc. An experienced programmer should be able to grasp the meaning of the individual instructions, operations, definitions etc. without any problems.
→ Verifiability (by programmers and not just by compilers etc.) (→ correctness, robustness)
→ Maintainability (since the programs can also be understood by other programmers)
→ Extensibility (since the programs can also be understood by other programmers)

4.2 Writability

Use a programming language and environment that will help you write the code.
The program code should be able to be written as simply as possible. On the one hand, the programming language should make it possible to write simple and elegant code. On the other hand, the program tools should support you as well as possible when creating the code.

Advantages:

  • Code can be created faster.
  • Code can be formatted automatically.
  • Errors / warnings are promptly reported by the programming environment.
  • Errors are avoided (for example when code fragments are generated automatically).
→ correctness
→ Comprehensibility (→ correctness, robustness, maintainability, expandability)

4.3 Steadiness, continuity

Write steady code.
Write your code so that small changes to the specification result in even small changes to the code.
→ Maintainability (the code can be quickly adapted to new circumstances)
→ Extensibility (the code can be quickly adapted to new circumstances)
→ Reusability (the code can be quickly adapted to new circumstances)

4.4 Configurability, Customizability

Write configurable code.
In general, constant values ​​should not be inserted directly into the code, but should be defined separately as constant values ​​(exception: trivial constants that will certainly never change, such as comparisons with the value). Constants that influence the program behavior should generally be read from a configuration file when the program is started.
→ Consistency (→ maintainability, expandability, reusability)

4.5 Don't repeat yourself, DRY[1]

Do not repeat yourself.
Code should not be duplicated and then not modified at all or only marginally modified.
→ Consistency (→ maintainability, expandability, reusability)
→ Comprehensibility (since there is less code) (→ correctness, robustness, maintainability, expandability)
→ Robustness (since no inconsistent changes are possible in several places)

4.6 Repeat yourself, RY[2]

Repeat yourself.
In user interfaces, it should always be possible for the user to perform the same or comparable tasks in the same way. The same identifiers, the same or similar operating elements, the same design, etc. should be used.
→ Reusability (since similar elements do not have to be implemented multiple times; DRY)
→ Consistency (→ maintainability, expandability, reusability)
→ Comprehensibility (since there is less code) (→ correctness, robustness, maintainability, expandability)

4.7 Demeter Law[3], Law of Demeter, LoD

"Just talk to your closest friends."
An object should only call methods of objects that it knows "personally":
  • Objects that are stored in status variables
  • Objects accessible through direct relationships
  • Objects that were passed using parameters when the method was called
  • Objects that the current object created itself
→ Consistency (→ maintainability, expandability, reusability)
→ Comprehensibility (since the number of communication partners is lower) (→ correctness, robustness, maintainability, expandability)

4.8 Verifiability, verifiability

Write verifiable code.
The correctness of a software package should be platform-independent and it should be possible to check it automatically. For this purpose, many programming paradigms and project techniques require that appropriate software tests are implemented at the same time as the software (module tests, unit tests). It is even better if the semantics of the program can be formally specified and checked (abstract data types, integrity constraints, ...)
→ Correctness (especially if the fulfillment of the specification is verified, i.e. formally proven)
→ Robustness (if the checks are also carried out)
→ Portability (because of the platform independence)

4.9 Use interfaces, Make Use of Interfaces

Use interfaces to communicate with objects, modules, etc.
The use of interfaces to access and modify data / information (instead of direct access) makes it possible to change code locally without affecting other objects, modules, etc. (as long as the interfaces do not change).
→ specification
→ Comprehensibility (→ correctness, robustness, maintainability, expandability)
→ Consistency (→ maintainability, expandability, reusability)
→ Verifiability (→ correctness, robustness, portability)
→ modularity

4.10 Use integrity constraints, Make Use of Integrity Constraints, Design by Contract[4]

Use and observe integrity constraints.
Whenever possible, integrity conditions - pre conditions, post conditions, invariants, assertions, type definitions, etc. - should be defined and compliance with them checked.
→ specification
→ correctness
→ robustness
→ Verifiability (→ correctness, robustness, portability)

4.11 Liskov's principle of substitution[5], LSP, substitution principle, Liskov substitution principle[6]

Don't override methods with unexpected code.
A method should not be overridden in such a way that an object of a derived class surprisingly behaves differently than one would expect based on the definition of the base class. In other words: methods that are redefined in derived classes must observe all integrity constraints (i.e. the specification) of the base class. This principle can therefore be viewed as a special case of the previous principle.
→ specification
→ correctness
→ robustness

4.12 Modularity, modularity, divide and rule, divide et impera

divide and conquer
A complex problem (plan, project, ...) can only be brought under control by breaking it down into smaller, preferably independent sub-problems (sub-projects, phases, processes, ...) until these can be solved (= manageable ) are. A program should therefore modularized, i.e. in individual Modules be subdivided. Each module should only be responsible for one task and perform it correctly and robustly.

4.12.1 Five requirements from Bertrand Meyer

Bertrand Meyer was one of the first to recognize and describe the importance of modularity. He formulated a total of five requirements that should be taken into account when defining modules:[4]

4.12.1.1 Modular decomposability
Break down a problem into different, separately solvable sub-problems.
→ Comprehensibility (→ correctness, robustness, maintainability, expandability)
→ Reusability (if the modules are largely independent of each other)
→ expandability
4.12.1.2 Modular composability
Modules should be able to be used in as many (different) situations / applications as possible.
This means that it should be possible to combine modules in different ways to form new functional units.
→ reusability
→ expandability
→ maintainability
→ Verifiability (→ correctness, robustness, portability)
4.12.1.3 Modular understandability
The tasks of a module should be understood without knowing many other modules.
→ Comprehensibility (→ correctness, robustness, maintainability, expandability)

This is a special case of the "intelligibility" principle.

4.12.1.4 Modular continuity
Small changes to the requirements should only result in changes to a small number of modules.
In the best case, only a single module is affected.
→ Consistency (→ maintainability, expandability, reusability)

This is a special case of the "continuity" principle.

4.12.1.5 Modular robustness, modular protection
A module should handle all abnormal cases itself.
That is, it shouldn't rely on another module to just use the interfaces as specified.
→ correctness
→ robustness
→ Verifiability (→ correctness, robustness, portability)
→ maintainability

4.12.2 Six principles by Bertrand Meyer

From these requirements, Bertrand Meyer derives six principles that should be observed when developing modules.

4.12.2.1 Syntactical units
Modules are syntactic units.
It should be possible to translate modules independently of one another and make them available in libraries.
→ reusability
→ correctness
→ robustness
→ Verifiability (→ correctness, robustness, portability)
→ maintainability
4.12.2.2 Few interfaces, few interfaces
Modules should have few interfaces.
Modules should communicate with as few other modules as possible.
→ reusability
→ Comprehensibility (→ correctness, robustness, maintainability, expandability)
4.12.2.3 Lean interfaces, small interfaces
Modules should have lean interfaces.
Interfaces shouldn't be overloaded with functionality. This means that two modules should communicate with each other via interfaces that are as extensive as possible.
→ maintainability
→ Verifiability (→ correctness, robustness, portability)
4.12.2.4 Explicit interfaces
Modules should communicate via explicit interfaces.
A module should not communicate with other modules via global variables or other implicit communication paths, but via explicit interfaces.
→ Comprehensibility (→ correctness, robustness, maintainability, expandability)
4.12.2.5 (Data) encapsulation, secret principle, encapsulation, information hiding
Information should be encapsulated in modules.
Any information that is not necessary to understand or use the tasks or functionality of a module should not be accessible from outside.
→ correctness
→ robustness
→ Verifiability (→ correctness, robustness, portability)
→ reusability
→ Comprehensibility (→ correctness, robustness, maintainability, expandability)
4.12.2.6 Open-closed principle
Modules should be both open and closed.
Modules should be open to changes as well as closed against changes. This means that a functioning module should not be changed if possible, but on the other hand it should be possible to adapt a module to new circumstances without any problems. In object-oriented languages, this is mainly achieved through inheritance, overwriting of methods and the use of abstract classes (especially interfaces).
→ Reusability (if modules are open)
→ Expandable (if modules are open)
→ Robustness (when tested modules are closed)
→ Maintainability (when functioning modules are closed; every change to a module may result in further changes → this should be avoided if possible)

4.12.3 Further module principles

Since the pioneering work of Bertrand Meyer in the late 1980s, further principles have been developed that affect the definition of modules.

4.12.3.1Use design patterns[7]
Use the module “templates” defined in design patterns.
There are many repetitive tasks in programming, such as stepping through a set of objects. There are tried and tested module “templates” for numerous such tasks. These describe which interfaces, classes, objects etc. are required to solve the respective task.
→ reusability
→ correctness
→ robustness
→ Comprehensibility (→ correctness, robustness, maintainability, expandability)
4.12.3.2 Separation of Concerns[8]
Each task is fulfilled by exactly one module.
So you divide the "responsibilities" among the modules, otherwise the advantages of the modularization are partly lost again.
4.12.3.3 Single Responsibility Principle[9]
Each task is performed by exactly one module and each module performs exactly one task.
In object-oriented programming, modularization is sometimes even carried out so far that not only is at most one object responsible for each task (Separations of Conerns), but, conversely, that each object is also responsible for exactly one task (single responsibility principle).
In other words, for every module there is exactly one reason why it has to be changed: The one task it has to do changes.
→ robustness
4.12.3.4Interface segregation principle[10], Interface Segregation Principle
Interfaces that are too large should be divided into several interfaces.
A module that uses an interface should only be presented with those methods that it really needs. This principle formulates a concrete way of realizing the lean interfaces required by Meyer.
→ maintainability
→ reusability
→ Verifiability (→ correctness, robustness, portability)

5 sources

  1. Hunt, Thomas (2003): Andrew Hunt and David Thomas; The Pragmatic Programmer; Publisher: Fachbuchverlag Leipzig im Carl Hanser Verlag; ISBN: 3446223096, 978-3446223097; 2003; Source quality: 5 (book)
  2. Kowarschick (MMProg): Wolfgang Kowarschick; Lecture “Multimedia Programming”; University: Augsburg University of Applied Sciences; Address: Augsburg; Web link; 2018; Source quality: 3 (lecture)
  3. Lieberherr, Holland (1989): Karl J. Lieberherr and Ian M. Holland; Assuring Good Style for Object-Oriented Programs; in: IEEE software; Volume: 6; Number: 5; Page (s): 36-48; Publisher: IEEE Computer Society Press; Address: Los Alamitos, CA, USA; 1989; Source quality: 5 (article)
  4. 4,04,1Meyer (1997): Bertrand Meyer; Object-oriented software construction; Edition: 2; Publisher: Prentice Hall International; ISBN: 0136291554; 1997; Source quality: 5 (book)
  5. Liskov, Wing (1993): Barbara Liskov and Jeannette M. Wing; Family Values ​​- A Behavioral Notion of Subtyping; College: Carnegie Mellon University; Address: Pittsburgh, PA, USA; Web link; 1993; Source quality: 5 (technical report)
  6. WikipediaEN: Liskov substitution principle: Wikipedia authors; Wikipedia, the free encyclopedia - Liskov substitution principle; Organization: Wikimedia Foundation Inc .; Address: San Francisco; http://en.wikipedia.org/w/index.php?title=Liskov_substitution_principle&oldid=499629316; 2012; Source quality: 5 (web)
  7. Gamma et al. (1995): Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides; Design Patterns - Elements of Reusable Object-Oriented Software; Edition: 1; Publisher: Addison-Wesley Longman; Address: Amsterdam; ISBN: 0201633612; 1995; Source quality: 5 (book)
  8. WikipediaEN: Separation_of_concerns: Wikipedia authors; Wikipedia, the free encyclopedia - Separation_of_concerns; Organization: Wikimedia Foundation Inc .; Address: San Francisco; http://en.wikipedia.org/w/index.php?title=Separation_of_concerns&oldid=508337060; 2012; Source quality: 5 (web)
  9. WikipediaEN: Single responsibility principle: Wikipedia authors; Wikipedia, the free encyclopedia - Single responsibility principle; Organization: Wikimedia Foundation Inc .; Address: San Francisco; http://en.wikipedia.org/w/index.php?title=Single_responsibility_principle&oldid=507275547; 2012; Source quality: 5 (web)
  10. Martin (1996): Robert C. Martin; The Interface Segregation Principle; in: C ++ Report; Volume: 8; Web link; 1996; Source quality: 5 (article)
  1. Wintersteiger, Mathis (2011): Andreas Wintersteiger and Christoph Mathis; Clean Code - Principles in developing clean code; in: Developer Magazine; Volume: 2011; Number: 5; Page (s): 13-20; Address: Frankfurt am Main; ISSN: 1619-7941; 2011; Source quality: 5 (article)
  2. Kowarschick (MMProg): Wolfgang Kowarschick; Lecture “Multimedia Programming”; University: Augsburg University of Applied Sciences; Address: Augsburg; Web link; 2018; Source quality: 3 (lecture)

6 See also

  1. Software engineering
  2. Wikipedia (EN): DRY (Web)
  3. WikipediaEn: Category: Programmingprinciples
  4. Wikipedia: Principles of Object-Oriented Design
  5. WikipediaEn: Code smell

TO BE DONE

Principle of Least Surprise