Structure chart
A structure chart is a diagrammatic representation of the modular structure of a computer program or system, depicting the hierarchical organization and interrelationships among modules in a time-independent manner.[1] It uses boxes to symbolize modules, connected by arrows to illustrate data and control flows, with the top-level module serving as the executive control point from which subordinate modules branch downward.[1] This visual tool breaks down complex systems into manageable, lowest-level functional units, focusing on what the program does rather than sequential execution details.[1]
Developed in the late 1960s by Larry Constantine during his work at C-E-I-R, Inc., and refined through empirical analysis at IBM's Systems Research Institute, structure charts emerged as a core element of structured design methodology.[1] By 1967, Constantine had established foundational graphics and vocabulary for program structures, evolving the concept over nearly a decade with input from practitioners to address real-world design challenges.[1] The approach was formalized in the 1979 book Structured Design: Fundamentals of a Discipline of Computer Program and Systems Design by Edward Yourdon and Larry Constantine, which presented structure charts alongside metrics for coupling and cohesion to promote modular, maintainable software.[1]
Structure charts serve multiple purposes in software engineering, including facilitating the design, documentation, debugging, maintenance, and implementation of programs by clarifying module interactions and subordination.[1] They emphasize principles of low coupling—minimizing inter-module dependencies—and high cohesion—ensuring modules perform cohesive functions—to achieve efficient, transform-centered architectures derived from data flow analysis.[1] Key components include module types such as afferent (input), efferent (output), transform (processing), and coordinate (control) modules, along with annotations for procedural elements like conditional or iterative calls, enabling top-down testing and optimization.[1] Unlike flowcharts, which emphasize sequence, structure charts prioritize architectural clarity, avoiding line crossings and supporting hierarchical shapes like recursive or "mosque-like" forms for better readability.[1]
Fundamentals
Definition
A structure chart is a hierarchical diagram used in software engineering to represent the modular decomposition of a system, illustrating how high-level modules break down into subordinate submodules and interact with one another. It employs boxes to denote modules and arrows to depict connections, providing a visual model of the system's architecture without specifying internal algorithms or procedural logic. This representation emphasizes the organization of components in a top-down manner, facilitating the understanding of system partitioning and interdependencies.[1]
Originating in the context of structured programming, structure charts were introduced by Larry Constantine and popularized through the book Structured Design, first published in 1975 and revised in 1979, co-authored with Edward Yourdon, as a tool for top-down design that visualizes control flow—such as module activations and transfers—and data sharing between components. Unlike traditional flowcharts, which detail dynamic execution sequences and time-dependent processes like loops and decisions, structure charts offer a static, time-independent view focused on modular hierarchy rather than sequential operations. This distinction allows designers to prioritize architectural clarity over procedural details, aiding in maintenance and scalability assessments.[2][1]
Central characteristics of structure charts include their tree-like hierarchy, where a root module at the top subordinates to lower levels of increasing detail; explicit depiction of module calls through solid arrows indicating control transfer from superordinate to subordinate modules; and the notation of data couples—labeled arrows or annotations showing parameters passed between modules to represent data exchange while minimizing unnecessary coupling. These elements collectively underscore the chart's role in promoting modular cohesion and loose inter-module dependencies.[1]
Key Components
A structure chart consists of module nodes, which are depicted as rectangular boxes representing distinct functional units within the system. Each box is labeled with a descriptive name, often using a verb followed by a specific process identifier, such as "GETAGENDATA" or "SCANWORD1," to clearly indicate the module's purpose. These nodes are typically numbered for hierarchical reference, corresponding to elements like transforms in associated data flow diagrams, facilitating easy identification and mapping during design and analysis.[1]
The hierarchy levels in a structure chart organize these modules in an inverted tree format, with the root module positioned at the top level to represent the highest-level function, such as "MAIN" or "TRANSEDIT." This root decomposes vertically into subordinate modules across multiple levels, illustrating a top-down breakdown of the system's logic into increasingly detailed subcomponents. The design adheres to the single-entry/single-exit principle, ensuring that each module has one entry point for activation and one exit point for completion, which promotes modularity and simplifies control flow management.[1]
Links and arrows connect the module nodes, serving as directed lines that depict both control flow and data flow between modules. Control flow is shown through solid arrows indicating invocation or activation of subordinate modules, such as subroutine calls, with a dot at the arrow's tail indicating a control reference; dashed arrows denote asynchronous control. Data flow, on the other hand, is shown through dashed arrows illustrating the passage of inputs and outputs, often annotated to highlight parameter transfers, and marked by a circle at the arrow's tail to distinguish it from pure control elements. These connections emphasize afferent (upward data movement), transform (processing), and efferent (downward data movement) branches within the hierarchy.[1]
Data couples provide specific notation for shared data elements passed between modules, typically represented as entry/exit data pairs along the arrows or in accompanying tables. These couples denote parameters exchanged during module interactions, such as input characters to a scanning module and output words from a processing module, with control parameters often underlined for emphasis. By focusing on these pairs, data couples help minimize inter-module dependencies while maintaining high cohesion within each module, without specifying implementation details like storage mechanisms.[1]
Construction and Notation
Building Process
The building process of a structure chart begins with a clear system specification, typically derived from data flow diagrams or functional requirements, to ensure the resulting hierarchy accurately reflects the system's modular organization. This methodical approach, rooted in structured design principles, emphasizes top-down decomposition to promote modularity and clarity in software architecture.[1]
The first step involves identifying the main module, which serves as the top-level entry point representing the overall system function. This module encapsulates the primary purpose of the system, such as coordinating inputs, processing, and outputs, and is determined by analyzing the high-level data flows and control requirements from the specification. For instance, in a data processing system, the main module might oversee the entire transaction cycle from input acquisition to output generation.[1] (pp. 42-43, 281-284)
Next, decompose the main module into subordinate modules through functional decomposition, where each subordinate handles a single, well-defined responsibility to achieve high cohesion. This involves breaking down complex functions into afferent modules for input handling, transform modules for core processing, and efferent modules for output management, ensuring no module overlaps in duties and adhering to the principle that each piece corresponds to one small aspect of the problem. Module nodes in this hierarchy, connected by links, form the basic building blocks during decomposition.[1] (pp. 19, 52, 177-181, 289-294)
Subsequently, define the interfaces between modules, specifying control flows for coordination and data flows for information exchange to minimize coupling. Interfaces are established by mapping inputs and outputs across module boundaries, using descriptive parameters to clarify dependencies without introducing side effects, thereby treating each module as a black box with precise entry and exit points. This step ensures that only essential data and control signals traverse connections, facilitating independent module development.[1] (pp. 68-71, 82-83, 184, 237-239)
The process concludes with iterative refinement, where the structure is repeatedly reviewed and adjusted to incorporate transaction structures such as sequence for ordered execution, selection for conditional branching, and iteration for repetitive operations. During refinement, designers check for and eliminate unstructured elements like spaghetti code by enforcing hierarchical control and recursive validation against the original specification. Validation criteria focus on confirming that the resulting hierarchy supports reusability through high fan-in and modularity, as well as testability via independent module verification, often using bottom-up or top-down strategies to assess completeness.[1] (pp. 49-50, 202-222, 295-300, 342-344)
Symbols and Conventions
Structure charts employ a standardized set of graphical symbols to represent the modular decomposition of software systems, originating from the structured design methodology. Modules, the fundamental units, are depicted as rectangles or boxes containing descriptive labels such as action names (e.g., "COMPUTE NET PAY"). Special types include double-lined rectangles for macros, striped rectangles for pre-existing or library modules, and labeled "DATA DIVISION" rectangles for data-only components. Arrows indicate interactions: solid lines denote control flows or subroutine calls from a parent module to subordinates, while dashed lines represent data flows or asynchronous transfers between modules. Looping arrows signify iteration or recursion, and pathological connections—such as arrows ending inside a module—are used sparingly to highlight direct data access or control references, often marked with dots or circles at the tail.[1]
Additional symbols enhance specificity for control structures. Diamonds illustrate conditional decisions, such as IF-THEN-ELSE branches labeled with "T" for true and "F" for false paths. For repetitive calls, curved or looping arrows denote loops, with annotations for conditions (e.g., "X ≠ Y" for DO-WHILE). Stubs, representing undefined or placeholder modules, are shown with dashed lines or empty rectangles to indicate incomplete refinements. Data flows are further annotated with small arrows or footnotes specifying parameters (e.g., "XE" for input data). These elements ensure the chart visually captures the hierarchical and procedural relationships without ambiguity.[1][3]
Conventions for drawing structure charts emphasize clarity and hierarchy to facilitate top-down design. The layout follows a tree-like, top-down structure, with the root module at the top and subordinates arranged below in levels approximating execution depth; processing flows left-to-right among siblings to reflect lexical or sequential order. Numbering schemes aid navigation, such as assigning transform-based identifiers (e.g., "4" for a specific module) or hierarchical labels like "1.1" for submodules under the main module "1," often combined with descriptive names (e.g., "GET CONTROL SPECS"). Cycles are generally avoided to maintain acyclic hierarchies, though controlled recursion is permitted via looping arrows for iterative designs; crossing lines are prohibited, with off-page connectors used for complex charts to preserve readability. Fan-out (number of subordinates, ideally 3-4) and fan-in (number of callers) are balanced to avoid overly wide or deep structures, promoting modular cohesion.[1][4]
Variations in notation exist, particularly when distinguishing structure charts from related diagramming techniques like Nassi-Shneiderman charts. While structure charts use arrows and hierarchical boxes to emphasize module calls and data/control flows, Nassi-Shneiderman diagrams employ nested rectangles without arrows, focusing on algorithmic control structures (sequence, selection, iteration) through enclosure and adjacency to enforce structured programming principles and eliminate unstructured jumps. This makes Nassi-Shneiderman more compact for low-level pseudocode representation but less suited for high-level system decomposition compared to the call-focused arrows in structure charts.[1][5][6]
Best practices for structure charts prioritize labeling for clarity, with each module and arrow annotated with precise names, parameters, or conditions to document interfaces and avoid ambiguity. Procedural notes alongside elements specify execution details, such as one-shot invocations marked by "1" in superordinate boxes. To differentiate flows, solid arrows for control are contrasted with dashed for data, and balanced hierarchies (e.g., "mosque-shaped" layouts) are favored over skewed ones; dummy modules serve as stubs during iterative refinement, ensuring the chart evolves without disrupting the overall notation. These conventions, rooted in structured design principles, promote maintainable and verifiable software architectures.[1][3]
Applications and Analysis
In Software Engineering
Structure charts play a pivotal role in top-down design within software engineering, particularly during the requirements analysis and detailed design phases, where they enable the decomposition of complex systems into hierarchical modules to plan modular code structures. This approach begins with a high-level module representing the overall system function and progressively refines it through successive levels of detail, ensuring each module focuses on a single, well-defined task. By visualizing the hierarchical relationships and data flows between modules, structure charts facilitate stepwise refinement, allowing developers to address the problem layer by layer without premature commitment to implementation details.[1][7]
In structured programming paradigms, structure charts integrate seamlessly by mapping modules directly to functions or procedures in languages such as Pascal and C, promoting the use of sequence, selection, and iteration constructs to enforce single-entry/single-exit control flow. Each module in the chart corresponds to a subroutine or function with clearly defined inputs and outputs, minimizing global data dependencies and supporting data coupling for loose interconnections. This mapping aids in translating the hierarchical design into code, where afferent modules handle input, central transform modules process data, and efferent modules manage output, aligning with the principles of cohesion and modularity inherent to structured languages.[1][8]
Structure charts enhance team development by facilitating the division of labor, as the modular hierarchy allows independent teams to work on separate submodules without interfering with others, provided interfaces are well-defined. The clear delineation of module boundaries and dependencies supports parallel implementation, design reviews, and integration, reducing coordination overhead and enabling incremental testing with stubs for unfinished components. This team-oriented structure improves project visibility and efficiency, as seen in methodologies where hierarchical modularity aligns with programming team workflows.[8][1]
Despite the dominance of object-oriented methods, structure charts retain modern relevance in the maintenance and refactoring of legacy systems, where reverse engineering techniques reconstruct charts from existing procedural code to reveal module hierarchies and dependencies. In such contexts, they aid in comprehending monolithic codebases, identifying refactoring opportunities like extracting functions, and documenting updates without altering external behavior. For instance, in reengineering efforts for legacy banking software, structure charts capture module interactions to support renewal processes and reduce maintenance risks.[9]
Advantages and Limitations
Structure charts offer several key advantages in software engineering design, primarily by promoting modularity through the decomposition of complex programs into smaller, independent modules with well-defined interfaces.[1] This hierarchical organization enforces high cohesion within modules and low coupling between them, facilitating easier implementation, debugging, and maintenance by reducing interdependencies and duplication of code.[1] Additionally, structure charts enhance the understanding of complex systems by providing a clear, visual representation of the control hierarchy and data flow, allowing designers to grasp the overall architecture without delving into procedural details.[1] They also support effective testing strategies, such as module isolation, top-down integration, and bottom-up testing, as the explicit boundaries enable incremental validation and minimize debugging efforts across the system.[1] Furthermore, by breaking down the system into predictable units, structure charts aid in estimating development effort, as module sizes and interactions can be quantified to forecast costs and schedules more accurately.[1]
Despite these benefits, structure charts have notable limitations stemming from their static nature, which focuses solely on the hierarchical organization and does not capture runtime behaviors, such as execution sequences or dynamic interactions.[1] This time-independent representation ignores aspects like conditional flows or asynchronous events, making it inadequate for analyzing how the system operates during execution.[10] They also struggle with modeling parallel processing or concurrent operations, as the single-threaded hierarchy lacks mechanisms to depict multiprocessing or interrupts effectively.[1] Similarly, structure charts do not accommodate object-oriented concepts like inheritance, limiting their applicability in modern paradigms that rely on polymorphism and encapsulation.[10] For very large systems, scalability becomes an issue, as the charts can grow unwieldy with numerous modules, leading to multi-page diagrams that are difficult to navigate and maintain.[1]
To mitigate these limitations, hybrid approaches that combine structure charts with complementary tools, such as data flow diagrams for functional analysis or UML diagrams for dynamic modeling, enable a more comprehensive design process by addressing both static structure and runtime dynamics.[1]
Examples and Variations
Basic Examples
A basic example of a structure chart can be found in a simplified payroll processing system, where the root module, labeled "Generate Payroll," decomposes into subordinate modules that handle input validation, pay calculation, and report generation.[11] The "Validate Input" submodule receives data couples such as employee ID and payroll records from the root, performs checks for data integrity, and passes validated records downward. This branches into the "Calculate Pay" submodule, which further decomposes into subroutines for gross pay computation, tax withholding, and social security deductions, using inputs like hours worked and rates to produce net pay outputs. Finally, the "Generate Report" submodule takes the net pay and employee details to update records and print checks, illustrating a sequential hierarchy where each level refines the overall payroll function.[11]
Textually, this structure chart can be represented as:
Generate Payroll (Root)
├── Validate Input (employee ID, payroll record → validated record)
│ └── Read Payroll Record
│ └── Validate Payroll Record
├── Calculate Pay (validated record → net pay)
│ ├── Calculate Gross Pay
│ ├── Calculate Tax Withheld
│ └── Calculate SS Withheld
└── Generate Report (net pay, employee ID → updated record, check)
├── Update Employee Record
└── Print Check
Generate Payroll (Root)
├── Validate Input (employee ID, payroll record → validated record)
│ └── Read Payroll Record
│ └── Validate Payroll Record
├── Calculate Pay (validated record → net pay)
│ ├── Calculate Gross Pay
│ ├── Calculate Tax Withheld
│ └── Calculate SS Withheld
└── Generate Report (net pay, employee ID → updated record, check)
├── Update Employee Record
└── Print Check
This hierarchy reflects the functional breakdown of payroll processing, where data flows unidirectionally from top to bottom, revealing module dependencies such as the reliance of pay calculation on validated inputs without needing to examine the underlying code.[11]
Another straightforward example is a simple calculator program that demonstrates sequence structure through arithmetic operations like addition and subtraction.[12] The root module, "Main Calculator," calls a "Get Input" submodule to receive two numbers and an operation flag (e.g., add or subtract), which then sequences to either the "Add" or "Subtract" submodule based on the flag. The "Add" submodule takes the two numbers as inputs and returns their sum to the root for display, while the "Subtract" submodule similarly computes and returns the difference, ensuring a linear flow without complex branching.[12]
A textual pseudo-diagram for this calculator structure chart appears as:
Main [Calculator](/page/Calculator) (Root)
├── Get Input (numbers a, b; flag → a, b, operation)
└── Process Operation (a, b, operation → result)
├── Add (a + b → result)
└── [Subtract](/page/Subtract) (a - b → result)
Main [Calculator](/page/Calculator) (Root)
├── Get Input (numbers a, b; flag → a, b, operation)
└── Process Operation (a, b, operation → result)
├── Add (a + b → result)
└── [Subtract](/page/Subtract) (a - b → result)
Through these examples, structure charts highlight module interdependencies and control flows—such as how the calculator's operations depend on prior input retrieval—providing a high-level view of program organization independent of implementation details.[13]
Advanced Variations
Transaction structure charts extend traditional structure charts by incorporating decision points and iterative elements to model systems driven by multiple transaction types, such as those in inventory management where processes like order processing, stock updates, and queries branch based on input conditions or repeat for batch operations.[14] In transaction analysis, a central dispatcher module routes incoming transactions to specialized subordinate modules, using symbols like filled circles for control parameters that influence conditional calls or loops, enabling the representation of selective multiplicity (if-then-else structures) and iterative multiplicity (do-while loops) without violating structured programming principles.[15] This variation is particularly suited for event-driven or data-flow intensive applications, as outlined in structured design methodologies, where the chart's hierarchy reflects transaction flows rather than pure transform sequences.[3]
Approaches to integrate structured and object-oriented design have been explored, using structure charts for functional decomposition alongside class hierarchies and object diagrams to implement hybrid information systems, as in a 1993 case study of a traffic count system combining structured development in SPSS/REXX with object-oriented development in Ada.[16] Such methods employ entity-relationship models as a common foundation, mapping data flows to object behaviors while maintaining separate visualizations for procedural and object interactions, aiding transitions in mixed paradigms.
In embedded systems and distributed architectures, structure charts have been adapted to depict resource-constrained module interactions and communication protocols, often including annotations for timing constraints or network latencies to support designs where modules span multiple nodes.
A canonical example from structured design involves transforming a data flow diagram of an invoice processing system into a structure chart, with afferent, central transform, and efferent modules handling input validation, computation, and output, as illustrated in the foundational text.[1]
Emerging trends leverage integrated development environments (IDEs) to automate structure chart generation from existing codebases, overcoming the limitations of manual creation by reverse-engineering hierarchies and dependencies. In Visual Studio, code map features generate dependency graphs akin to structure charts, visualizing method calls, class relationships, and control flows directly from C# or C++ source code, thus enabling rapid refactoring and maintenance in large-scale projects.[17] This tool-assisted approach, supported by extensions for flowchart and UML diagram generation, promotes dynamic updates and integration with version control, making structure charts viable in agile and continuous integration workflows.[18]