about
2/21/2022
DesignBites Repo
DesignBites Code Repo

DesignBites  Repository

Short story about Design, with code examples

Quick Status Many short bites and demos no known defects Demonstration code a few examples, more later Documentation yes Test cases NA Static library NA Build requires Rust, C++, C# installed Planned design changes Add more bites and demo code
"We want to make our programs elegant and simple, make their intents clear, and make them quick and reliable. That is most likely to happen if we think first about design."
- First Things blog

Contents:

Bites List, Structures List
Design Track Summary - first Bite
Design Bites are a short sequence of pages, each focused on a specific aspect of software design. They are brief, pragmatic, and relevent to things we do professionally. The design examples: Basic, Factored, DataFlow, TypeErase, and PlugIn all have code that implements a simple file line counting process, along with commentary about what distinguishes each. That simplicity allows us to focus on the structure of the design - how are these structures different? Why should we chose one? How do we implement it?

Bites:

Here are the current Design Bites:

  1. Design Track Summary
    Design: What?, Why?, So What?, Why Not?

  2. Introduction
    TextFinder design: Concept development, Architecture, TextFinder Specification, Implementation

  3. Design
    Initial thoughts about design: concept, design, design evolution, design document, building a design, presenting designs

  4. Structure
    Why does TextFinder require a flow architecture?

  5. Basic
    Monolithic structure with code implementing file line counting.

  6. Factored
    Factored: Executive, Input, Compute, Output - code with user-defined types and tests.

  7. DataFlow
    DataFlow: components arranged in data pipeline - code with user-defined types and tests.

  8. TypeErase
    TypeErase: components with interfaces and object factories - code with user-defined types and tests.

  9. PlugIn
    PlugIn: Output component is plugged into Compute at run-time - code with user-defined types and tests.

Summary of Structures:

The structure demos, below, all implement the same simple functionality: count lines in a specified file. The purpose is to keep code small enough that it is easy to see how structural variations affect size and complexity. Each of the structures, presented in the table below, has implementing Rust Code in DesignStructure Code repository. You can see there what is required to support each of them and Rust idioms needed to make that work.
Structure Diagram size Pros - The good news is: Cons - the bad news is: What changed
Basic Fig 1. Basic 120 lines simple, easy to test for small code sizes as code size increases: hard to understand and test nothing yet
Factored Fig 2. Factored 336 lines If only one package is changed, only that one is compiled. Much easier to understand and test. Project gets more complex with more pieces to track and deploy. Executive has to participate in each stage of the processing. Created three new packages, all of which Executive depends on.
DataFlow Fig 3. DataFlow 242 lines Continuous output - good ergonomics for user. Executive doesn't need to handle data. Harder to implement and test piece by piece. Most applications will need test mocks. Changed ownership. Now have a chain of dependencies. Each user-defined type depends on its downstream sibling.
TypeErase Fig 4. TypeErase 284 lines Same as DataFlow plus Input, Compute, and Output are now decoupled. Each depends only on interfaces provided by upstream component. Construction is more complex. Each component needs to use factory function to create its down-stream component. Introduced traits specified by caller and implemented by called. That reverses the dependency chain, so called depends on caller.
PlugIn Fig 5. PlugIn 321 lines Same as TypeErase plus freedom to define Output processing at run-time through a polymorphic dispatch. The Executive can decide which of several output implementations to use based on command line input. Same as TypeErase plus Executive needs access to Compute to configure it with Output. Removed parameterization of Compute since we want to specify Output at run-time. Need to hold Output in an Option since it is not available until after startup.
The Design Structure code is a good place to increase your familiarity with Rust syntax and idoms.
  Next Prev Pages Sections About Keys