NivaarExam PrepOfficial exam papers ↗

25-Comp-B11 Advanced Software Design · December 2018

Question 22 of 28: Programming to an Interface, Not to an Implementation

Nivaar worked solution (AI-drafted; not reviewed by a licensed engineer)

Notes on this paper

17-Comp-B11 Advanced Software Design — National Exams, December 2018. 3 hours, closed book exam with up to 2 aid sheets allowed (written on both sides), no calculator permitted. The paper is organized into five parts, and candidates were instructed to answer any five (5) questions in Part I, any three (3) in Part II, any four (4) in Part III, any two (2) in Part IV, and any five (5) in Part V — only the first questions answered, in each part, as they appear in the answer book are marked. All questions carry equal weight, so the 19 questions actually marked (5+3+4+2+5 of 28) each count for 100/19 ≈ 5.26% of the paper. All 28 questions are answered below for completeness.

Reference texts: Sommerville, Software Engineering (10th ed., Pearson) — software processes, requirements engineering, design principles, dependability; Pressman, Software Engineering: A Practitioner's Approach (9th ed.) — supplementary process and quality coverage; Gamma, Helm, Johnson & Vlissides (GoF), Design Patterns: Elements of Reusable Object-Oriented Software — creational/structural/behavioural pattern catalogue and the "program to an interface, not an implementation" / "favor object composition over class inheritance" principles; Sebesta, Concepts of Programming Languages (12th ed.) — polymorphism, dynamic binding, inheritance and language-level object semantics; Bertrand Meyer, Object-Oriented Software Construction — design by contract, preconditions/postconditions/invariants; Barbara Liskov's 1987 substitutability paper for Question 11; Karl Wiegers, Software Requirements (3rd ed.) — the functional/quality/process/implementation/business requirements taxonomy of Question 2; Kruchten, The Rational Unified Process: An Introduction, for Question 1; Myers, The Art of Software Testing, for Questions 6 and 28.

PART I — General Principles (answer any 5 of 7)

PART V — C++/Java and Modular Programming (answer any 5 of 7)

Question 22: Programming to an Interface, Not to an Implementation (Part V)

Question text not reproduced: the examination questions are © Engineers and Geoscientists BC. Open the official past paper (linked at the top of this page) to read the question, then follow the worked solution below.

The principle says that client code should declare its variables, parameters, and return types using an ABSTRACT type (an interface or abstract base class) that describes only the operations it needs, never a specific CONCRETE class — so the client depends on WHAT an object can do, not on WHICH exact class provides it.

Violating the principle (Java):

ArrayList<String> names = new ArrayList<>();
void printAll(ArrayList<String> list) { ... }

Here printAll's parameter type is the CONCRETE class ArrayList. Any caller holding a different List implementation (a LinkedList, for instance) cannot call printAll at all without first copying its data into a new ArrayList, and if the concrete implementation is later swapped project-wide (e.g., for a LinkedList better suited to frequent insertions), every method signature naming ArrayList must change.

Following the principle (Java):

List<String> names = new ArrayList<>();
void printAll(List<String> list) { ... }

Now printAll depends only on the List interface's operations (get, size, iteration). The concrete instance assigned to names can be swapped — new LinkedList<>() instead of new ArrayList<>() — with zero change to printAll or to any other code that only ever names the List interface.

C++ equivalent uses a pointer/reference to an abstract base class with pure virtual functions: a function taking Shape& s (an abstract base with a pure virtual draw()) works unmodified whether the actual object passed is a Circle or a Square, whereas a function taking a concrete Circle& can never accept a Square at all.

Why it matters. This is the exact mechanism that makes Question 17's Template Method extensible (client code calls validate() on a CardValidator-typed reference, never on a named concrete subclass) and is the concrete implementation technique underlying the open–closed principle: new implementations of the interface can be added without touching client code that depends only on the interface itself.