Design Principles Mid

1 / 48

How do violations of design principles contribute to technical debt over time?

Select the correct answer

1

Violations compound as coupling and duplication accumulate, making later changes slower, riskier, and more costly.

2

Violations improve short-term speed and reduce debt because skipping structure lets teams ship features faster.

3

Violations are isolated defects that linter tools remove automatically, so they rarely affect long-term maintenance.

4

Violations only slow initial delivery, but well-tested code afterward pays the debt back with no interest.

Why do we need design principles at all? What underlying problem, managing complexity, change, or coupling: are they all ultimately trying to solve?

Select the correct answer

1

They ultimately exist to eliminate all bugs so systems never require testing or review after they ship.

2

They ultimately exist to standardize syntax so teams write identical-looking code across every project they build.

3

They ultimately exist to enforce performance so systems run faster and consume fewer resources as they grow.

4

They ultimately exist to manage complexity so systems stay understandable and changeable as they grow.

What makes a module 'good'? What properties distinguish a well-designed module from a poorly designed one?

Select the correct answer

1

It has many public methods and global state, exposing internals so callers can tune behavior directly.

2

It has minimal comments and short names, hiding intent so only original authors can safely modify it.

3

It has high cohesion and low coupling, exposing a clear interface that hides its implementation details.

4

It has low cohesion and tight coupling, sharing data widely so other modules integrate with it faster.

Explain the Open/Closed Principle. How do you design a module to be open for extension but closed for modification without touching the existing source code?

Select the correct answer

1

Add new behavior through global configuration flags, since branching on flags avoids writing any new classes.

2

Add new behavior by copying whole modules, since duplicating existing source avoids breaking any current callers.

3

Add new behavior by directly editing existing classes, since modifying source keeps all logic in one place.

4

Add new behavior through new abstractions or subclasses rather than editing existing, tested source code.

Explain the Liskov Substitution Principle. Why is it a problem if a subclass cannot be used interchangeably with its parent class?

Select the correct answer

1

Subclasses must always call the parent's constructor to ensure the base state is properly initialized first.

2

Subclasses must not add any new methods beyond those already declared in the parent class's interface.

3

Subclasses must override every method of the parent so that behavior is fully replaced and stays consistent.

4

Subtypes must be substitutable for their base types without breaking the program's expected correctness.

What is the 'fat interface' problem, and how does the Interface Segregation Principle help in reducing the impact of changes on client code?

Select the correct answer

1

Interfaces expose private data fields; ISP hides them behind getters so clients cannot break encapsulation.

2

Classes implement too many interfaces; ISP merges them into one so clients keep a single clean dependency.

3

Interfaces grow too large in memory; ISP reduces runtime overhead by loading only the needed method tables.

4

Clients depend on methods they don't use; ISP splits interfaces so unrelated changes don't affect them.

How do the SOLID principles specifically improve the testability of a codebase?

Select the correct answer

1

Following SOLID removes the need for tests by guaranteeing correctness through strict type-safe contracts.

2

Combining responsibilities into large classes reduces the number of test files you must write and maintain.

3

Depending on abstractions lets you swap real dependencies for mocks, isolating the units under test.

4

Injecting concrete classes directly makes tests faster because no abstraction layer must be resolved first.

What is the difference between SRP and the Interface Segregation Principle? Why shouldn't we just have one large interface for all related actions?

Select the correct answer

1

SRP and ISP both mean one method per type, so a single interface would end up violating each principle equally.

2

SRP applies to interfaces while ISP applies to classes; both aim to reduce the number of methods per file.

3

SRP limits a class's responsibilities; ISP keeps interfaces small so clients avoid unused method dependencies.

4

SRP splits large interfaces; ISP splits large classes, together ensuring every module has exactly one caller.

What does it mean to 'program to an interface, not an implementation', and how does this principle enable polymorphism at the design level?

Select the correct answer

1

Prefer inheritance over composition so subclasses always inherit the parent's concrete behavior.

2

Expose every internal method publicly so callers can reach the implementation details directly.

3

Depend on abstractions describing behavior so any implementation can be substituted freely.

4

Write concrete classes first, then extract interfaces only after the code has fully stabilized.

Why is it better to have many specific interfaces rather than one general-purpose interface? How does this relate to decoupling?

Select the correct answer

1

Fewer interfaces mean fewer files, which makes the overall codebase simpler to navigate.

2

One large interface guarantees consistency, so every client shares the same set of methods.

3

Clients depend only on the methods they actually use, which lowers coupling between them.

4

Specific interfaces let a single class implement them all, increasing reuse across modules.

How do you identify 'tight coupling' in a codebase, and what are the symptoms of a system that is too tightly coupled?

Select the correct answer

1

Each class holds a single responsibility, making the code easy to extend but slow to compile fully.

2

Duplicated logic appears across files, yet every module can still be deployed independently of others.

3

Modules communicate only through clean interfaces, so refactoring one rarely affects the others at all.

4

A small change ripples through many modules, and classes cannot be tested or reused in isolation.

Explain how high cohesion within a module improves the testability and maintainability of the software.

Select the correct answer

1

A focused single-purpose module has fewer dependencies, so its tests are simpler and changes stay local.

2

A module split across many files hides complexity, so maintainers can change one part without reading others.

3

A module doing many tasks shares more code, so fewer test cases are needed and refactoring is much faster.

4

A module with global state exposes internals, making integration tests easier and unit tests less important.

What is the difference between 'Fragility' and 'Immobility' in software design, and how does high coupling contribute to both?

Select the correct answer

1

Fragility is slow build times after edits; immobility is code that can never be deleted safely; loose coupling is the shared root cause.

2

Fragility is breakage in unexpected places after a change; immobility is the inability to reuse code elsewhere; high coupling drives both.

3

Fragility is the inability to reuse code elsewhere; immobility is breakage in unexpected places after a change; low cohesion drives both.

4

Fragility is many bugs shipped at release; immobility is a team's reluctance to refactor code; poor naming conventions cause both issues.

What is 'stamp coupling', and how does passing entire objects when only a field is needed hurt a design?

Select the correct answer

1

A module receives a whole object but uses one field, so it needlessly depends on the full structure and breaks when unrelated parts change.

2

A module shares a global object with others, so it silently reads stale values and produces wrong results when another module edits them.

3

A module copies an object before using it, so it wastes memory on duplicates and diverges when the original is later mutated elsewhere.

4

A module receives one field but needs the whole object, so it repeatedly re-queries the source and slows down when the data set grows large.

What is the Law of Demeter (Principle of Least Knowledge)? Why is 'reaching through' an object to access its internal dependencies considered a design smell?

Select the correct answer

1

An object should only talk to objects of the same class; chaining through others hides internal structure and duplicates code in callers.

2

An object should only talk to its immediate collaborators; chaining through them exposes internal structure and couples callers to it.

3

An object should never hold references to others; storing them creates cycles and prevents the garbage collector from freeing the callers.

4

An object should minimise the number of its methods; calling too many of them wastes memory and slows down the callers at runtime badly.

Explain the 'Tell, Don't Ask' principle. How does it help preserve the encapsulation of an object's state?

Select the correct answer

1

Notify observers whenever state changes so dependent objects can pull the latest values on demand

2

Instruct an object to perform an action itself rather than querying its state and deciding externally

3

Expose public getters and setters for every field so collaborators can read and mutate state freely

4

Query an object for all its fields first, then let the caller apply the business rules on those values

What is the 'Law of Demeter' (or Principle of Least Knowledge), and how does 'not talking to strangers' help in reducing coupling?

Select the correct answer

1

An object should minimize the total number of public methods it exposes to keep its overall interface as small as possible

2

An object should never hold references to other objects and must obtain every collaborator through a global registry

3

An object should call only its own, its parameters', and its direct collaborators' methods, avoiding long chains

4

An object should communicate with distant modules only through events, never by calling methods on them directly at all

What does 'Tell, Don't Ask' mean? How does it help in moving logic closer to the data it operates on?

Select the correct answer

1

Split the object into a data holder and a service so the logic stays in a dedicated stateless helper

2

Read the object's data into the caller so the shared logic can be reused across many different callers

3

Cache the object's fields locally so repeated questions about its state avoid extra round trips each time

4

Send commands to the object owning the data so the decision logic lives beside the state it uses

What is the design goal of 'Information Hiding', and how does it protect a system from the 'ripple effect' of changes?

Select the correct answer

1

Duplicate shared state across modules so each keeps its own copy and remains isolated from other edits

2

Conceal volatile decisions behind stable interfaces so changes stay local and don't propagate to clients

3

Encrypt internal data so unauthorized modules cannot read it, which prevents malicious changes from spreading

4

Publish every internal detail up front so clients adapt early and no surprises ripple through later

Why do we need Abstraction at all? What is the difference between Abstraction and Information Hiding (Encapsulation)?

Select the correct answer

1

Abstraction is only for interfaces and base classes; hiding applies exclusively to concrete implementation classes

2

Abstraction models the essential idea to manage complexity; hiding conceals the details that realize it

3

Abstraction restricts access to private members; hiding groups related data and behavior into one unit

4

Abstraction improves runtime speed by removing indirection; hiding adds layers that slow the whole system down

What is a 'leaky abstraction', and how does it violate the principle of encapsulation?

Select the correct answer

1

An abstraction that leaks implementation details callers must know, undermining the hiding encapsulation promises.

2

An interface that hides too much behavior, so callers cannot access any of the useful underlying details.

3

A design where private fields are exposed via getters, letting external code freely modify their state.

4

A memory leak caused when an object retains references and prevents the garbage collector from reclaiming it.

What is the 'Feature Envy' code smell, and which principle guides you to move behavior closer to the data it uses?

Select the correct answer

1

A method with far too many parameters; the Single Responsibility principle splits it into separate concerns.

2

A class with too many public methods; the Interface Segregation principle splits it into smaller focused roles.

3

A method that duplicates logic elsewhere; the Don't Repeat Yourself principle extracts it into a shared helper.

4

A method obsessed with another class's data; the Information Expert principle moves behavior to that data.

What does 'Encapsulate what varies' mean as a design principle, and how do you identify the parts of a system most likely to change?

Select the correct answer

1

Freeze stable core logic into constants; find them by locating code that has never once been modified before.

2

Hide all internal fields behind getters and setters; find them by checking which variables are declared private.

3

Duplicate volatile code across modules for safety; find them by measuring which functions get called most often.

4

Isolate the parts likely to change behind stable interfaces; find them by spotting requirements and details that shift.

What is the Single Level of Abstraction Principle (SLAP), and how does mixing abstraction levels in one function hurt readability?

Select the correct answer

1

Each function should operate at one level of abstraction; mixing high- and low-level steps hurts readability.

2

Each function should have a single return point; mixing multiple exits scattered through the body hurts readability.

3

Each module should depend on one other layer; mixing calls across many layers in one place hurts readability.

4

Each class should expose only one public method; mixing several unrelated operations in one type hurts readability.

Why is 'composition over inheritance' a common design maxim, and what are the risks of deep inheritance hierarchies (the fragile base class problem)?

Select the correct answer

1

Inheritance runs faster at runtime; deep composition chains add indirection that slowly degrades overall performance.

2

Inheritance hides implementation better; deep composition exposes internal helper objects to unrelated calling code.

3

Composition gives flexible runtime behavior; deep inheritance couples subclasses so base changes silently break them.

4

Composition avoids all code reuse; deep inheritance forces subclasses to reimplement every inherited method again.

Why is deep inheritance often considered a code smell, and what is the 'Fragile Base Class' problem?

Select the correct answer

1

Changes to a base class can unexpectedly break distant subclasses that depend on its internal behavior.

2

Adding a new subclass forces recompiling every unrelated class living in the same package hierarchy.

3

Subclasses always run slower because each method call must traverse the entire chain of parent classes.

4

Base classes cannot define abstract methods, so subclasses are forced to duplicate shared logic everywhere.

What does it mean to 'favor composition over inheritance', and in what specific scenarios is inheritance still the superior choice?

Select the correct answer

1

Compose objects for flexibility; inheritance fits a true is-a relationship with stable, substitutable base behavior.

2

Compose objects for speed reasons; inheritance fits any deep hierarchy where subclasses override most parent methods.

3

Compose objects to save memory; inheritance fits any case where two classes happen to share a few methods.

4

Compose objects to hide fields; inheritance fits whenever you want to reuse code without writing wrapper types.

Explain the 'Rule of Three' in the context of refactoring toward DRY. Why shouldn't we abstract logic the first time we see repetition?

Select the correct answer

1

Abstract only after three developers have independently written the same code, because that proves the logic is genuinely reusable across separate teams.

2

Refactor duplication the very first time it appears, since delaying until a third copy exists makes the eventual abstraction far harder to extract.

3

Wait until code repeats a third time before abstracting, because two occurrences may be coincidental and the true shared pattern isn't yet clear.

4

Always split shared logic into exactly three separate layers, since fewer layers leave code coupled and more than three adds needless indirection cost.

Explain the KISS principle. How does adding layers of abstraction often violate this, and what is the cost to the team?

Select the correct answer

1

Keep designs as simple as possible; needless abstraction layers add indirection that raises cognitive load and slows the team's understanding.

2

Keep dependencies few; abstraction layers violate this by importing libraries, and the cost is a larger deployment artifact and slower startup time.

3

Keep interfaces stable; abstraction layers violate this by changing method signatures, and the cost is that dependent modules break during releases.

4

Keep every class small; abstraction layers violate this by growing file sizes, and the cost is that builds and automated test suites run slower.

How does 'premature optimization is the root of all evil' function as a design principle, and how do you decide when optimization is actually warranted?

Select the correct answer

1

It requires that all performance work be delegated to compilers rather than any manual effort

2

It says you should optimize every hot path up front so later refactoring becomes unnecessary

3

It means optimization should be avoided entirely because clean code always outperforms tuned code

4

It warns against tuning before knowing bottlenecks; optimize once profiling proves a real need

What is the Single Source of Truth principle, and how does it differ from DRY?

Select the correct answer

1

Both are identical rules requiring that code and data never be repeated anywhere in a system

2

Each piece of data has one authoritative home; DRY targets duplicated logic rather than data

3

It centralizes all business logic in one class; DRY concerns only naming conventions used

4

Each module owns its own data copy; DRY instead mandates copying logic across every layer

How does 'Separation of Concerns' differ from the Single Responsibility Principle?

Select the correct answer

1

SoC partitions a system into distinct concerns; SRP says a class has one reason to change

2

They are interchangeable names for the same rule that every function should do one thing

3

SoC applies only to classes while SRP governs how whole subsystems are split into layers

4

SoC forbids any shared state whereas SRP simply requires methods to be kept short overall

How does the principle of Separation of Concerns help in managing cognitive load for developers working on a large codebase?

Select the correct answer

1

It reduces the total line count so developers simply have fewer characters left to read overall

2

It isolates concerns so a developer reasons about one module without holding the whole system

3

It forces every developer to memorize all module interactions before any change can be made

4

It merges related concerns into one large module so all context lives in a single readable file

What is Inversion of Control as a concept, and how does the 'Hollywood Principle' (don't call us, we'll call you) relate to it?

Select the correct answer

1

A framework controls flow and calls your code back, which is what the Hollywood Principle states

2

It means inverting class hierarchies, and the Hollywood Principle is about avoiding deep subclassing

3

It is another name for dependency injection only, unrelated to any callback or framework flow

4

Your code drives the framework by polling it, and the Hollywood Principle describes that polling

Explain the 'Information Expert' principle. How do you decide which class should be responsible for a specific piece of logic?

Select the correct answer

1

Assign the responsibility to the class nearest the user interface receiving the initial request

2

Assign the responsibility to the class that already holds the data needed to carry it out

3

Assign the responsibility to a dedicated manager class that coordinates all the other classes

4

Assign the responsibility to whichever class currently has the fewest methods defined on it

Explain the principle of Command-Query Separation. Why should a method that changes state not return a value, and vice versa?

Select the correct answer

1

Every public method should combine a read and a write so callers make only one round trip to it

2

Queries change state and return data, while commands merely read state without altering anything at all

3

Commands and queries must both return a status code so callers can verify the operation succeeded

4

Commands change state and return nothing; queries return data and cause no side effects

What is the 'Fail-Fast' design principle, and why is it better for a system to crash early rather than continue in an unstable state?

Select the correct answer

1

Detect invalid conditions and stop immediately, preventing corrupted state and making the bug visible

2

Retry invalid conditions repeatedly and hope they resolve, keeping the service available to end users

3

Route invalid conditions to a backup instance, so the primary process can keep serving traffic normally

4

Suppress invalid conditions and keep running, deferring the failure until a scheduled maintenance window

What is defensive programming, and how does it relate to 'Design by Contract' (preconditions and postconditions)?

Select the correct answer

1

It is identical to Design by Contract, since both require every method to verify its own postconditions before returning any result to the caller.

2

It codes only the happy path and trusts all callers; Design by Contract adds the runtime checks that defensive programming deliberately leaves out.

3

It codes against invalid states and misuse; Design by Contract instead assumes preconditions hold, shifting that duty explicitly to the caller.

4

It replaces contracts entirely by throwing exceptions, whereas Design by Contract forbids exceptions and relies purely on validated return codes.

What specific design choices make a piece of code 'hard to test,' and which principles (like DIP or ISP) directly address these issues?

Select the correct answer

1

Using dependency injection makes wiring implicit; the DIP fixes this by requiring classes to construct their own collaborators directly.

2

Pure functions with no side effects resist testing; the ISP fixes this by adding shared global state that assertions can then read.

3

Hard-coded concrete dependencies block substitution; the DIP fixes this by depending on abstractions injectable in tests.

4

Small focused interfaces block mocking; the ISP fixes this by merging them into one broad interface that tests can stub in a single place.

What design principle does a 'God Object' violate, and what is the standard strategy for refactoring it?

Select the correct answer

1

It violates the Liskov Substitution Principle; make it a base class others can freely substitute for, preserving all inherited behavior.

2

It violates the Single Responsibility Principle; extract its distinct responsibilities into smaller focused, collaborating classes.

3

It violates the Dependency Inversion Principle; introduce an interface it implements so callers depend only on that shared abstraction.

4

It violates the Open/Closed Principle; add subclasses that override its methods so behavior can be extended without any modification.

What are the benefits of 'programming to an interface, not an implementation', and how does this principle facilitate unit testing?

Select the correct answer

1

Callers depend on a concrete class, so the compiler inlines calls, and tests run faster by exercising the real production object each time.

2

Callers share one global implementation, reducing object count, and tests verify behavior directly against that single shared instance's state.

3

Callers know the exact type, enabling private fields to be read in assertions, so tests need no mocks and cover more real internal paths.

4

Callers depend on an abstraction, so implementations swap freely and tests inject mocks or fakes for the real collaborator.

What are some common 'code smells' (like Feature Envy or Shotgun Surgery) that indicate a violation of a specific design principle?

Select the correct answer

1

Feature Envy means duplicated code across modules, and Shotgun Surgery means one method grows too long and must be broken into helper functions.

2

Feature Envy means a class hides too much data, and Shotgun Surgery means a single class absorbs every responsibility that should be split up.

3

Feature Envy means an interface has too many methods, and Shotgun Surgery means a subclass cannot substitute cleanly for its declared base type.

4

Feature Envy shows misplaced responsibility, and Shotgun Surgery shows scattered concerns that one change forces across many classes.

What is 'Shotgun Surgery', and which design principle (SRP or Cohesion) is typically violated when this smell appears?

Select the correct answer

1

Duplicated code forces the same edit in many places; it violates DRY throughout the whole codebase repeatedly.

2

A single change forces many small edits across many classes; it violates cohesion because one responsibility is scattered.

3

One class doing many things forces edits when any concern changes; it violates SRP by concentrating responsibilities.

4

One change makes many classes change for differing reasons; it violates the Open/Closed Principle very broadly.

What are the code smells 'needless complexity' and 'opacity', and which design principles address them?

Select the correct answer

1

Needless complexity is deep inheritance (favor composition); opacity is dead code removed by regular refactoring passes.

2

Needless complexity is unused over-engineered abstraction (YAGNI/KISS); opacity is unclear code fixed by clarity.

3

Needless complexity is duplicated logic (DRY); opacity is tight coupling addressed by dependency inversion between modules.

4

Needless complexity is premature optimization (KISS); opacity is global state fixed by encapsulation and scoping.

What is the 'Principle of Least Astonishment,' and how do you apply it to API design?

Select the correct answer

1

APIs should expose every internal option so users can configure any behavior.

2

APIs should behave as users reasonably expect, so results never surprise them.

3

APIs should minimize the number of methods to keep the surface area small.

4

APIs should hide implementation by throwing exceptions on unexpected input.

What is the Principle of Least Privilege, and how does it apply to software design beyond just security?

Select the correct answer

1

Restrict privileges only at network boundaries where external attackers can reach.

2

Give each component only the access it needs, limiting coupling and impact of errors.

3

Give each component full access early so refactoring later becomes easier to manage.

4

Grant privileges based on developer seniority to keep codebase changes controlled.

Why is global mutable state considered an enemy of good design, and which principles does it violate?

Select the correct answer

1

It slows the program because global variables are stored far from the CPU cache.

2

It duplicates data across modules, breaking DRY and increasing binary size at runtime.

3

It hides dependencies and shared state, breaking encapsulation and hurting testability.

4

It prevents inheritance because globals cannot be overridden by derived subclasses.

Why is immutability considered a valuable design principle for reducing bugs and coupling?

Select the correct answer

1

Immutable objects can't change after creation, so they're safe to share and reason about.

2

Immutable objects run faster since the CPU can skip all bounds and null checks.

3

Immutable objects enforce inheritance so subclasses always keep the parent behavior.

4

Immutable objects use less memory because the compiler stores only a single copy.

Design Principles Mid Quiz | TechPrep