Object-Oriented Design Choices
eBook - ePub

Object-Oriented Design Choices

Adair Dingle

Condividi libro
  1. 328 pagine
  2. English
  3. ePUB (disponibile sull'app)
  4. Disponibile su iOS e Android
eBook - ePub

Object-Oriented Design Choices

Adair Dingle

Dettagli del libro
Anteprima del libro
Indice dei contenuti
Citazioni

Informazioni sul libro

Do modern programming languages, IDEs, and libraries make coding easy? Maybe, but coding is not design. Large-scale or expensive apps clearly require evaluation of design choices. Still, software design directly impacts code reuse and longevity even for small-scale apps with limited overhead. This text evaluates and contrasts common object-oriented designs.

A given problem may have many solutions. A developer may employ different design techniques – composition, inheritance, dependency injection, delegation, etc. – to solve a particular problem. A skilled developer can determine the costs and benefits of different design responses, even amid competing concerns. A responsible developer documents design choices as a contract with the client, delineating external and internal responsibilities. To promote effective software design, this book examines contractual, object-oriented designs for immediate and sustained use as well as code reuse. The intent of identifying design variants is to recognize and manage conflicting goals such as short versus long-term utility, stability versus flexibility, and storage versus computation. Many examples are given to evaluate and contrast different solutions and to compare C# and C++ effects. No one has a crystal ball; however, deliberate design promotes software longevity. With the prominence of legacy OO code, a clear understanding of different object-oriented designs is essential.

Design questions abound. Is code reuse better with inheritance or composition? Should composition rely on complete encapsulation? Design choices impact flexibility, efficiency, stability, longevity, and reuse, yet compilers do not enforce design and syntax does not necessarily illustrate design. Through deliberate design, or redesign when refactoring, developers construct sustainable, efficient code.

Domande frequenti

Come faccio ad annullare l'abbonamento?
È semplicissimo: basta accedere alla sezione Account nelle Impostazioni e cliccare su "Annulla abbonamento". Dopo la cancellazione, l'abbonamento rimarrà attivo per il periodo rimanente già pagato. Per maggiori informazioni, clicca qui
È possibile scaricare libri? Se sì, come?
Al momento è possibile scaricare tramite l'app tutti i nostri libri ePub mobile-friendly. Anche la maggior parte dei nostri PDF è scaricabile e stiamo lavorando per rendere disponibile quanto prima il download di tutti gli altri file. Per maggiori informazioni, clicca qui
Che differenza c'è tra i piani?
Entrambi i piani ti danno accesso illimitato alla libreria e a tutte le funzionalità di Perlego. Le uniche differenze sono il prezzo e il periodo di abbonamento: con il piano annuale risparmierai circa il 30% rispetto a 12 rate con quello mensile.
Cos'è Perlego?
Perlego è un servizio di abbonamento a testi accademici, che ti permette di accedere a un'intera libreria online a un prezzo inferiore rispetto a quello che pagheresti per acquistare un singolo libro al mese. Con oltre 1 milione di testi suddivisi in più di 1.000 categorie, troverai sicuramente ciò che fa per te! Per maggiori informazioni, clicca qui.
Perlego supporta la sintesi vocale?
Cerca l'icona Sintesi vocale nel prossimo libro che leggerai per verificare se è possibile riprodurre l'audio. Questo strumento permette di leggere il testo a voce alta, evidenziandolo man mano che la lettura procede. Puoi aumentare o diminuire la velocità della sintesi vocale, oppure sospendere la riproduzione. Per maggiori informazioni, clicca qui.
Object-Oriented Design Choices è disponibile online in formato PDF/ePub?
Sì, puoi accedere a Object-Oriented Design Choices di Adair Dingle in formato PDF e/o ePub, così come ad altri libri molto apprezzati nelle sezioni relative a Ciencia de la computación e Ciencias computacionales general. Scopri oltre 1 milione di libri disponibili nel nostro catalogo.

Informazioni

II
Strategic Type Coupling

CHAPTER 4
Composition

CHAPTER OBJECTIVES

  • Define OOD relationships
  • Illustrate composition and containment
  • Examine association, ownership and cardinality
  • Introduce Dependency Injection

4.1OBJECT-ORIENTED RELATIONSHIPS

A famous quote from Aristotle, “the whole is greater than the sum of its parts”, emphasizes the power of combination. By reusing and combining types, class designers may expediently construct new types and new interfaces. A central design question is how to do so. An implied design responsibility is to manage the dependency of the whole on its parts.
OOD defines different relationships (composition, containment, and inheritance) that determine the form and flexibility of reuse. How types are connected – association, cardinality, and ownership – differentiate design options. An association between two objects may be temporary, stable, or for the lifetime of the primary object. Cardinality may reflect a one-to-one or a one-to-many relationship, may be defined at the class or object level, and may vary or be stable. Ownership implies that the primary object is responsible for a secondary object, requiring explicit decisions for allocation, release, replacement, or transfer of ownership.
Basic structural relationships are has-a (composition), holds-a (containment), and is-a (inheritance). Historic OOD discussion defined aggregation as a structure where the aggregate object contains many subobjects of the same type. Aggregation addresses only form and not intent or effect. For example, both a container and a building toy (such as a Lego set) may be described as aggregates. However, a container retains no dependency on the subobject type while a building toy is strongly dependent on its components. A container illuminates a holds-a relationship where there is little restriction on the type of subobjects held while a composite illustrates a has-a relationship with significant dependency on the subobject type. While structurally similar, holds-a and has-a may be distinguished via design details such as association, ownership, lifetime, and reuse of functionality.
The simplest relationship is none: two types do not interact. Next in simplicity is the uses-a relationship where one type uses another in a transient fashion such as call by value. Other relationships represent associations that are more enduring and suggest some type dependency.

4.2CONTAINMENT (HOLDS-A)

Standard containers model the holds-a relationship well because there is no type dependency on the subobjects. A stack provides the same utility no matter what type of data held. A stack is well-defined when empty, full, or in-between. The operations of push(), pop(), clear(), etc. function in the same manner regardless of the type of data processed. The type of data stored provides no functionality and has little or no effect on containers. The holds-a relationship reflects little or no type dependency.
Example 4.1 portrays weak type dependency: a customer holds-a gift card. The no-argument constructor zeroes out the pointer defined to hold the address of a (heap-allocated) gift card, suggesting that a customer may operate without a gift card and that not all customers have a gift card. If a customer is well-defined without a gift card, then a customer may have zero gift cards and still function as a customer. A customer is not dependent on a gift card if gift cards do not drive core functionality, or if another item, such as a free shipping certificate, may replace a gift card.
Holds-a does not require ownership. The customer may not be responsible for the destruction of a gift card, especially if ownership is temporary. Disposal of a gift card may differ by design. If the customer is the sole owner of a dynamically allocated gift card, then the gift card should be ‘destroyed’ (reference zeroed out or destructor invoked) unless ownership is transferred out. Since the presence of a gift card is optional in the customer class of Example 4.1, any method that accesses the gift card must first test for existence, as is done in replace().
Example 4.1C++ Customer Holds-A Gift Card
// transient ownership of subobject(s)
// implies memory management
// => must provide destructor
// => support or suppress copying
class Customer // replaceable gift card
// handle only, no object yet
{ GiftCard* c = 0;
public:
// assumption constructor: ownership
// of transfer assumed
Customer(GiftCard*& transfer)
{ c = transfer;
transfer = 0;
}

// no argument constructor:
// no gift card allocated
Customer() { c = 0; }

// again ownership transferred in
void replace(GiftCard*& backup)
// dispose existing card
{ if (c) delete c;
c = backup;
backup = 0;
}
˜ Customer() { if (c) delete c; }
};
A container may hold objects, copies of objects or references to objects. The objects contained may be passed in and out, transferred, or destroyed (redeemed), yielding a fluctuating cardinality across the lifetime of the container. Logically, a customer may hold a positive number of gift cards, or none. If different gift card types are available (bonus, restricted by item or calendar date, etc.), the mix of gift card types held may vary over the lifetime of a customer. Only a temporary association exists between the customer object and the gift card object.
Independent of implementation language, a containment relationship is flexible because cardinality, ownership, and association may vary. Designs differ though because of implementation language. In C++, memory management must be addressed for any object with internally allocated heap memory. The class must track ownership so that all heap-allocated memory is deallocated before objects owning the heap-allocated memory go out of scope. In all languages, aliases should be tracked so that dead objects may be reclaimed and data is not corrupted.
Copying is an essential design decision. Often, it is undesirable to copy large collections either for data integrity or performance concerns. What are the effects of supporting or suppressing copying? What does a container hold: original data, duplicates, references? Copying may be more complex when data is referenced indirectly, that is, via a reference or a pointer. What is copied? – the address holder (reference or pointer), or the actual data values?
Copy semantics should be an explicit design decision. If a C++ class neither defines nor suppresses copying, the compiler generates a default copy constructor and overloaded assignment operator that yield shallow copies, and, thus aliasing and possibly data corruption. If no decision is made in C#, copying is also shallow. Recall the difference between shallow and deep copying as examined in Chapter 3.

4.3COMPOSITION (HAS-A)

An intuitive example of composition is a signal that relies on sensors. A signal is activated when some number or proportion of its sensors are triggered. An alarm clock uses a timer as a sensor; a security light uses a motion detector, etc. Type dependency is clear: a signal is not well-defined without sensors – it is inoperable. In a has-a relation, the subObject provides key functionality and affects the state of the composing object; for example, sensors affect the state of the signal. A sensor in a failed state affects...

Indice dei contenuti