01 / 21

Impact of
Program Design

Explore how design choices in code structure, algorithms, and data representation affect functionality, readability, and efficiency of software systems.

AP Computer Science A

What is Program Design?

Program design is the process of planning how a program will be structured before and during implementation. It encompasses decisions about class hierarchy, method decomposition, data representation, and algorithm selection.

Three Pillars of Good Design

Readability
Code that humans can understand: meaningful names, consistent formatting, clear logic flow.
Maintainability
Code that can be changed without breaking other parts: modular methods, low coupling, high cohesion.
Efficiency
Code that uses resources wisely: choosing appropriate algorithms and data structures for the task.

Why Design Matters

Project Timeline Cost of Change Design Coding Testing Deployed Poor Design Good Design

Core Principle: Method Decomposition

A well-designed program breaks complex tasks into small, focused methods. Each method should do one thing well and have a clear, descriptive name. This is the Single Responsibility Principle applied at the method level.

Monolithic processOrder() validate input calculate total apply discount charge payment send confirmation update inventory → validateInput() calculateTotal() applyDiscount() chargePayment() sendConfirmation() updateInventory() Decomposed

Class Design & Encapsulation

In Java, encapsulation means bundling data (instance variables) with the methods that operate on that data, while hiding internal state behind access modifiers. This is the foundation of robust class design.

1
Private instance variables: Declare fields as private so external code cannot directly modify them.
2
Public accessor/mutator methods: Provide getX() and setX() to control how data is read and changed.
3
Validation in mutators: Enforce invariants inside setters (e.g., reject negative values for age).

Procedural vs Object-Oriented

Procedural Object-Oriented
Organization Functions that act on separate data Objects that bundle data + behavior
Data Access Global or passed as parameters Private fields, controlled via methods
Reusability Copy-paste functions Inheritance & polymorphism
Scalability Hard to manage as size grows Modular: add classes independently
AP CSA Focus Background knowledge Primary paradigm tested

How to Apply Good Design

1
Identify the nouns: each major noun in the problem becomes a candidate class.
2
Identify the verbs: each action becomes a candidate method on the appropriate class.
3
Choose data types wisely: use int vs double, arrays vs ArrayList, based on requirements.
4
Minimize scope: keep variables as local as possible; use parameters instead of fields when data is temporary.
5
Test each method independently: small, well-named methods are easy to verify and debug.

Example: Poor Design

// Everything crammed into one method public static void main(String[] args) { double[] prices = {9.99, 24.50, 3.75}; double total = 0; for (int i = 0; i < prices.length; i++) { total += prices[i]; } double tax = total * 0.08; total += tax; System.out.println("Total: $" + total); // What if we need tax rate from another state? // What if we add discounts? Shipping? }

Example: Better Design

public class ShoppingCart { private ArrayList<Double> prices; private double taxRate; public ShoppingCart(double taxRate) { this.prices = new ArrayList<>(); this.taxRate = taxRate; } public void addItem(double price) { prices.add(price); } public double getSubtotal() { double sum = 0; for (double p : prices) sum += p; return sum; } public double getTotal() { return getSubtotal() * (1 + taxRate); } }

Design Impact: Algorithm Choice

Choosing the right algorithm is a critical design decision. Searching for an item in a sorted array can be done two ways:

Linear Search
Checks every element one by one. Time complexity: \( O(n) \). Works on any array, sorted or not.
Binary Search
Halves the search space each step. Time complexity: \( O(\log n) \). Requires a sorted array.

Choosing Data Representation

How you store data shapes what operations are easy or hard. The AP CSA exam expects you to reason about arrays vs ArrayLists and primitive vs reference types.

Array ArrayList
Size Fixed at creation Grows dynamically
Type Primitives or objects Objects only (autoboxing)
Insert/Remove Manual shifting: \( O(n) \) Built-in: still \( O(n) \)
Best When Size is known, speed matters Size varies, convenience matters

One public counting interface, two hidden mechanisms

Mechanical and electronic counting instruments have matching front controls and different interiors.Two implementations can provide the same public counting behavior while storing their internal state differently. A representation change must preserve the interface’s promised behavior.

Preserve public behavior across implementations

Two Counter implementations trace public outputs 0, 1, 2 and 3 while storing opposite internal values.Starting at zero, one Counter stores count and increments it; another stores negativeCount and decrements it, returning its negation. Three increment calls make both getCount results 3. Their private representations differ while the public trace agrees.

Design with Inheritance

Animal speak(), move() Dog speak() → "Bark" Cat speak() → "Meow" Fish move() → "Swim" Animal a = new Dog(); a.speak(); // "Bark" at runtime

Readable Code: Naming Conventions

✕ Bad Names
int x;
double d;
void doStuff()
boolean flag;
✓ Good Names
int studentCount;
double totalPrice;
void calculateGPA()
boolean isEligible;

Common Mistakes

✕ God Method
Putting all logic in a single method with 50+ lines. Break it into smaller, focused helper methods.
✕ Public Fields
Declaring instance variables as public instead of private. This breaks encapsulation and allows invalid states.
✕ Magic Numbers
Using raw literals like 0.08 instead of named constants like TAX_RATE. Hard to understand and change.

Design Principles Summary

Principle Good Practice Anti-Pattern
Method Size Small, single-purpose Monolithic "god method"
Data Hiding private fields + getters/setters public fields everywhere
Naming Descriptive: getTotal() Cryptic: gt()
Algorithm Match to data constraints Always brute-force
Reusability Inheritance, parameters Copy-paste code blocks

Question 1 of 5

Which of the following best describes the primary benefit of encapsulation in program design?

Question 2 of 5

A sorted array of \( 1{,}000{,}000 \) elements is searched using binary search. What is the maximum number of comparisons needed?

Question 3 of 5

What design flaw makes this change difficult to implement?

Question 4 of 5

A method named process() performs input validation, calculation, and output formatting. Which design principle does it violate?

Question 5 of 5

Which of the following is an advantage of using an ArrayList over a standard array?