liveBook · Manning

Object-oriented programming

As explained in Functional Design and Architecture: Examples in Haskell

A programming paradigm that organizes software around objects combining state with behavior and supports mechanisms such as encapsulation, inheritance, and polymorphism.

Object-oriented programming organizes design around object-oriented languages, concepts, patterns, and ideas. Its practical aim is to divide a large application into understandable parts, reducing the accidental complexity that makes software risky and expensive to maintain. It is imperative under the hood, but serves as a reasoning framework for turning requirements and domain models into high-level code structures. section 1.4 section 1.4.2 section 1.6

Objects and interfaces can isolate awkward dependencies behind a fitting contract. Rather than letting application code depend directly on a thermometer that reports Kelvin, an adapter can expose the Celsius-based sensor interface the application requires. This localizes conversion and protects the rest of the design from a mismatched API. section 1.4.2

Listing 1.5 Adapter pattern
final class HighAccuracyThermometer {                    #1
  def name() : String = "HAT-53-2"
  def getKelvin() : Float = {
      native.core.highAccuracyThermometer.getData()
  }
}
  
final class HAThermometerAdapter (                       #2
    thermometer: HighAccuracyThermometer) 
  extends ISensor {
    val t = thermometer                                  #3
    
    def getData() : Float = {                            #4
        val data = t.getKelvin()
        native.core.utils.toCelsius(data)
    }
    def getName() : String = t.name()
    def getDataType() : String = "temperature"
}

The adapter example shows an object wrapping a high-accuracy thermometer, converting Kelvin to Celsius, and implementing the required sensor interface. section 1.4.2

Object-oriented patterns provide general, language-agnostic responses to recurring design problems. They are useful tools, not automatic answers: some structures, such as command and strategy, can require many classes, while higher-order functions, lambdas, and closures may express comparable behavior more concisely in a functional style. section 1.4.2

Maintainability and reuse depend on explicit responsibilities and dependable interfaces:

  • Use contracts to state behavior that implementations must honor; otherwise behavior becomes difficult to predict. section 1.4.3
  • Apply SOLID principles to reason about responsibility, interfaces, substitution, and dependencies. section 1.4.3
  • Require substitutions to be transparent to client code. An implementation that throws an unexpected exception through a shared interface violates the Liskov substitution principle. section 1.4.3
  • Favor low coupling and high cohesion to keep complexity manageable; these principles are not exclusive to object-oriented code. section 1.6

Lamp substitution failure

A routine can switch off a list through an ILampSwitcher interface. DaylightLamp honors that contract, but TableLamp throws an exception while switching. Replacing the interface with that implementation therefore forces client code to handle behavior it was not promised, exposing a broken substitution contract. section 1.4.3

UML can communicate object-oriented designs through class diagrams, while use-case diagrams remain implementation-paradigm agnostic. Design choices should be guided by the problem and architecture rather than by assuming that a diagram or principle belongs to only one programming paradigm. section 1.3 section 1.6

How Functional Design and Architecture: Examples in Haskell covers it

How deep it goes
Explains patterns, contracts, SOLID, substitution failures, and coupling, while contrasting functional alternatives rather than detailing object internals.
Examples
Uses a Kelvin-to-Celsius thermometer adapter and a lamp interface whose implementation violates Liskov substitution.
What it assumes
Assumes familiarity with object-oriented languages while introducing patterns, contracts, UML roles, and SOLID principles through examples.
What you can do after
Evaluate/understand object-oriented design decisions using patterns, contracts, SOLID principles, low coupling, and high cohesion.
How it connects
Connects object-oriented programming with imperative programming, UML, design patterns, SOLID, contracts, interfaces, coupling, cohesion, and functional programming.

Also explained in

Compare how 9 books explain object-oriented programming →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Functional Design and Architecture: Examples in Haskell. The section links point to the parts of the book it draws on.