CS504 — Midterm Summary (Lectures 1–22)
📘 Lecture 1 — Introduction to Software Engineering
📖 Overview: This lecture introduces Software Engineering as a discipline, explaining what software truly is, why it matters, and how it differs from other engineered systems. It covers the origins of software engineering from the software crisis, defines the field through authoritative sources, and discusses the challenges of balancing conflicting requirements in software development.
🗂️ Topics Covered
The lecture begins by defining software beyond just code to include data and documentation. It then explores why software is critically important across business, science, games, and embedded systems. The distinction between computer science and software engineering is clarified through the lens of engineering as applied science. Key differences between software and physical systems are examined, including the fact that software does not wear out and the inherent complexity due to constant change. The software crisis of the 1960s is presented as the catalyst for software engineering. Formal definitions from IEEE and Ian Somerville are provided, followed by characteristics of well-engineered software and the balancing act between cost, reliability, efficiency, and user-friendliness. The law of diminishing returns is introduced, along with an overview of major software development activities.
📝 Lecture Summary
1.1 Introduction
Software engineering is about learning how to develop good software using examples and case studies. Before understanding software engineering, we must first understand what software actually is.
What is Software? When we write a program for a computer, we call it software. However, software is not just a program; it includes several components:
- Program: The code itself is definitely included.
- Data: The data on which the program operates is also considered part of the software.
- Documentation: All related documents are also considered part of the software.
So software is not just code written in Cobol, Java, Fortran, or C++. It also includes data and all documentation.
Why is it important? Software plays a vital role in all fields of life today:
- Business decision-making: Software helps analyze data and make business decisions accurately and easily.
- Modern scientific investigation and engineering problem solving: Software enables intensive calculations and data analysis, such as DNA decoding in bioinformatics and astronomical observations.
- Games: Computer games that interest people of all ages are driven by software.
- Embedded systems: Microcontrollers in cars, televisions, and microwave ovens are controlled through software.
Software is also central to education, office automation, and Internet applications. Billions and trillions of dollars are invested in this field worldwide every year.
Engineering: The process of productive use of scientific knowledge is called engineering.
1.2 Difference between Computer Science and Software Engineering
Engineering is defined as "the science concerned with putting scientific knowledge to practical use." Various engineering fields like electrical, mechanical, and civil engineering are based on physics. Physics itself is not engineering, but using physics to make buildings, electronic devices, and machines is engineering. Similarly, computer science relates to software engineering as physics relates to other engineering fields.
🔑 Definition — Software Engineering: "This is the process of utilizing our knowledge of computer science in effective production of software systems."
Difference between Software and Other Systems: The major thing that distinguishes a software system from other systems is that software does not wear out! Non-software systems like cars, TVs, or electric bulbs can malfunction due to wear and tear over time. They have a particular life after which they may not perform as expected. Software is not affected by this phenomenon. If a software has a defect (called a bug), that defect exists from the very first day. You cannot remove a bug by simply replacing a faulty part with a new one—getting a new CD will not fix it. This is a fundamental difference between software and other systems.
💡 Why this matters: Understanding that software does not wear out means that all defects are design-time errors, not time-based degradation. This shifts the focus to getting the design right from the start.
1.3 Source of Inherent Complexity of Software
Non-software systems like cars have very infrequent and minor changes between models—a slight body shape change or a new gadget, but rarely a fundamental engine change. In contrast, software companies constantly make fundamental changes to their systems—enhancements, interface changes, or entirely new systems. Changes happen in many different dimensions and with high frequency. This high frequency of change is a major reason for increased bugs in software. If a car manufacturer released fundamentally changed cars every six months without proper testing, those cars would also have lots of bugs. Therefore, one major reason for complexity in software is that software passes through a constant process of evolution. The name of the game is change and evolution all the time in all dimensions.
1.4 Software Crisis
What is Software Crisis? In the early 1950s, computers were primitive and software use was limited. By the 1960s, rapid hardware improvements made computers far more powerful, leading to more complex software. The tools and techniques used for less complex software became inapplicable. This is like a person who built a hut being asked to build a concrete building using the same methods—it would not work. In the early 1960s, software suffered from a similar problem called the Software Crisis. Using old tools and techniques for large systems resulted in:
- Projects were not complete in most cases
- Delivered too late
- Over-budgeted
- Systems were not reliable—they could not do what they were expected to do
A conference was held in 1960 where the term "software crisis" was introduced. The major issue was that software development was in crisis and we had not been able to handle its complexities. The term Software Engineering was also coined in that same conference. People realized that just coding is not enough—engineering principles must be applied to software development.
1.5 Software Engineering
Software Engineering as defined by IEEE: The Institute of Electrical and Electronic Engineers (IEEE) defines software engineering as: "The application of a systematic, disciplined, quantifiable approach to the development, operation, and maintenance of software; that is, the application of engineering to software."
Another definition by Ian Somerville: "All aspects of software production. Software engineering is not just concerned with the technical processes of software development but also with activities such as software project management and with the development of tools, methods and theories to support software production."
Software Engineering is the combination of all tools, techniques, and processes used in software production, including:
- Programming Language
- Programming Language Design
- Software Design Techniques
- Tools
- Testing
- Maintenance
- Development
Programming language design is a major success in software engineering—for example, the design of Ada language was a considerable effort. Object-oriented programming requires languages that support object-orientation to implement object-oriented designs.
Well-Engineered Software: Characteristics include:
- Provides the required functionality
- Maintainable
- Reliable
- Efficient
- User-friendly
- Cost-effective
Every company can build software with unlimited resources, but well-engineered software conforms to all these characteristics. Software has a close relationship with economics—engineering systems always require economic feasibility analysis. The major challenge for a software engineer is to build software within limited time and budget in a cost-effective way with good quality.
The Balancing Act! Software Engineering is a balancing act. There are always trade-offs between conflicting requirements:
- Cost vs. Efficiency
- Cost vs. Reliability
- Efficiency vs. User-interface
A software engineer must analyze which feature is more important and strike a balance. For example, in a cruise missile or nuclear reactor controller, performance and reliability are far more important than cost-effectiveness and user-friendliness. The Chernobyl accident illustrates what happens when software does not react within a certain time. The art of good balance comes from experience.
Law of Diminishing Returns: When you dissolve sugar in water, sweetness increases gradually, but at a saturation point, no more sugar dissolves. Similarly, in software engineering, when you invest in improving quality, initially a little money yields high improvement. But after reaching a certain level of quality, the return on investment becomes reduced—less than the effort or money invested. Therefore, after a reasonable level of quality, we usually do not try to improve further.
Software Background: Caper Jones, a renowned researcher, analyzed around 10,000 software projects through his company Software Productivity Research. He divided software activities into about 25 categories; nine major ones include:
- Project Management
- Requirement Engineering
- Design
- Coding
- Testing
- Software Quality Assurance
- Software Configuration Management
- Software Integration
- Rest of the activities
No single activity is dominant—coding is only about 13-14% of the whole effort of software development.
Excerpt from "No Silver Bullet" – Fred Brooks: In the eye of an unsophisticated manager, software is like a giant that sometimes reveals as unscheduled delay or cost overrun. Managers look for magical solutions, but magic is not a reality. The only solution is to follow a disciplined approach to build software. Software Engineering is nothing but a disciplined and systematic approach to software development.
1.6 Summary
Today we discussed: what software engineering is, why it is important, what software crisis is, how software engineering derived from software crisis, the importance of engineering principles, the balancing act and how it applies, the law of diminishing returns, and the major activities involved in software development.
⭐ Key Takeaways
Software engineering is a disciplined, systematic, and quantifiable approach to developing, operating, and maintaining software—it is not just coding. The software crisis of the 1960s revealed that old techniques were inadequate for complex systems, leading to the birth of software engineering as a formal discipline. Software is fundamentally different from physical systems because it never wears out, but its constant evolution introduces inherent complexity and defects. A software engineer must balance conflicting requirements like cost, reliability, efficiency, and user-friendliness, recognizing the law of diminishing returns on investment. Most critically, coding represents only about 13-14% of total software development effort, with other activities like requirements engineering, design, and testing consuming the majority.
🧠 Quick Revision Questions
- What are the three main components that constitute software, according to this lecture?
- Why is it incorrect to say that a software program "wears out" over time like a physical machine?
- What was the "software crisis" and what event formally recognized it and coined the term "software engineering"?
- According to the IEEE definition, what does software engineering involve beyond just writing code?
- What is the "law of diminishing returns" as applied to software engineering, and what practical implication does it have for quality improvement?
📘 Lecture 02 — Introduction to Software Development
📖 Overview: This lecture introduces the fundamental concepts of software development as a disciplined engineering process. It distinguishes between construction and management activities, presents a software engineering framework centered on quality, describes the software development loop, and outlines the four basic phases of software engineering, emphasizing the critical importance of maintenance.
🗂️ Topics Covered
The lecture covers the division of software development into construction (requirements, design, coding, testing) and management (planning, configuration management, quality assurance, installation/training) activities. It presents a Software Engineering Framework with four components: quality focus, processes, methods, and tools. It describes the Software Development Loop (problem definition, technical development, solution integration, status quo) and the six questions of software construction. Finally, it explains the four Software Engineering Phases: vision, definition, development, and maintenance, highlighting the disproportionate cost of maintenance.
📝 Lecture Summary
2.1 Software Development
Software development activities are broadly divided into two major categories: construction and management. Construction activities are those directly related to building the software, such as gathering requirements, developing design, coding, and testing. Management activities are umbrella activities that complement construction to ensure it proceeds smoothly and effectively, including project planning and management, configuration management, software quality assurance, and installation/training. Management activities surround and govern construction activities through processes and rules, as illustrated in Figure 1.
🔑 Definition — Construction Activities: Activities directly related to the development of software, e.g., requirement gathering, design development, coding, and testing. 🔑 Definition — Management Activities: Umbrella activities used to smoothly and successfully perform construction activities, e.g., project planning, configuration management, software quality assurance, and installation/training.
2.2 A Software Engineering Framework
Any engineering approach must be founded on an organizational commitment to quality. Based on this, a software engineering framework is proposed with four major components:
- Quality Focus: Demands that processes be defined for rational and timely development, with quality emphasized during execution.
- Processes: A set of key process areas (KPAs) for effectively managing and delivering quality software in a cost-effective manner. Processes define tasks, their order, deliverables, and milestones.
- Methods: Provide the technical "how-to's" to carry out tasks. There can be multiple techniques for a task, used in different situations.
- Tools: Provide automated or semi-automated support for software processes, methods, and quality control.
🔑 Definition — Software Engineering Framework: A structured approach to software development founded on organizational commitment to quality, comprising quality focus, processes, methods, and tools. 💡 Why this matters: This framework provides a structured, layered approach ensuring that quality is built into the process from the top down, with methods and tools supporting defined processes.
2.3 Software Development Loop
Software development activities can be performed in a cyclic manner called the software development loop, which has four major stages:
- Problem Definition: Determine what problem the software will solve; completely comprehend the issues and requirements of the system.
- Technical Development: Find the solution on technical grounds and base the implementation on it; this is where the new system is actually developed.
- Solution Integration: Integrate any existing systems with which the new system must interact.
- Status Quo: The situation after the new system is successfully deployed at the user site. When new requirements emerge, the loop must be repeated.
Software Construction answers a sequence of six questions during development:
- What is the problem to be solved?
- What are the characteristics of the entity used to solve the problem?
- How will the entity be realized?
- How will the entity be constructed?
- What approach will uncover errors made in design and construction?
- How will the entity be supported over the long term (corrections, adaptations, enhancements)?
🔑 Definition — Software Development Loop: A cyclic model of software development consisting of problem definition, technical development, solution integration, and status quo, enabling evolution and integration.
2.4 Software Engineering Phases
There are four basic phases of software development:
- Vision: Determine why the system is being built and what business objectives to achieve.
- Definition: Realize or automate the vision; determine the activities and things involved.
- Development: Determine the design, implementation, and testing of the system.
- Maintenance: Control change in the system, whether enhancements or defect removal. This is a very important phase as for most large, long-lifetime systems, maintenance cost normally exceeds development cost by factors ranging from 2 to 3. A pathological case (Boehm, 1975) for an avionics system had development cost of $30 per line of code but maintenance cost of $4000 per instruction.
📐 Formula: Maintenance Cost vs. Development Cost → For large, long-lifetime systems, maintenance cost is typically 2 to 3 times the development cost. 📌 Example: An avionics system had a development cost of $30 per line of code but a maintenance cost of $4000 per instruction, illustrating the potential extreme disparity.
⭐ Key Takeaways
Software development is a multi-activity process that goes far beyond coding, requiring both construction activities (requirements, design, coding, testing) and management activities (planning, quality assurance, configuration management). The software engineering framework emphasizes that quality focus is the foundation, supported by processes, methods, and tools. The software development loop highlights the cyclic nature of development, where after status quo is reached, new requirements can restart the cycle. Finally, the four software engineering phases—vision, definition, development, and maintenance—show that maintenance is a critical, often dominant, cost phase, typically costing 2-3 times the initial development.
🧠 Quick Revision Questions
- What are the two major categories of software development activities, and how do they relate to each other?
- List the four major components of the Software Engineering Framework and explain the role of each.
- What are the four stages of the Software Development Loop, and what happens after the Status Quo stage?
- Name the four phases of software engineering and describe the primary activity in each phase.
- According to the lecture, how does the cost of maintenance typically compare to the cost of development for large, long-lifetime systems? Provide the specific example and numbers given.
📘 Lecture 3 — Requirement Engineering
📖 Overview: This lecture introduces the fundamental concept of requirement engineering as the critical "definition phase" of software development. It establishes why understanding and documenting what a system should do is the most important step in building successful software, highlighting the severe cost implications of getting requirements wrong.
🗂️ Topics Covered
The lecture begins by positioning requirement engineering within the software development lifecycle, specifically as the "definition phase" that transitions from "why" to "what." It then provides several formal definitions of software requirements from different experts, establishes the critical importance of requirements by citing defect statistics and cost-to-fix data, and finally explains the central role the requirements document plays in all subsequent development and management activities.
📝 Lecture Summary
3.1 Requirement Engineering
Software development is a multi-activity process that answers questions about the problem, the solution's characteristics, its realization, construction, error detection, and long-term support. These questions shape the 4 distinct phases of the software development life cycle: vision (why), definition (what), development (how to build), and maintenance (changes and enhancements). Requirement engineering deals with the definition phase, focusing on establishing system services and constraints. It is the starting point of development where the focus is on what needs to be built, not how to build it.
🔑 Definition — Software Requirements (Jones): A statement of needs by a user that triggers the development of a program or system. 🔑 Definition — Software Requirements (Alan Davis): A user need or necessary feature, function, or attribute of a system that can be sensed from a position external to that system. 🔑 Definition — Software Requirements (Ian Sommerville): A specification of what should be implemented; descriptions of how the system should behave, or of a system property or attribute; may be a constraint on the development process. 🔑 Definition — Software Requirements (IEEE):
- A condition or capability needed by a user to solve a problem or achieve an objective.
- A condition or capability that must be met or possessed by a system to satisfy a contract, standard, or specification.
- A documented representation of a condition or capability.
💡 Why this matters: While definitions vary slightly, they all converge on the same core idea: a software requirement is a document describing all services provided by the system and the constraints under which it must operate.
3.2 Importance of Requirements
Many problems in software development are traced back to shortcomings in the requirement gathering and documentation process. 40-60% of all defects found in software projects can be traced back to poor requirements. Fred Brooks, in his book "The Mythical Man Month," emphasizes that the hardest single part of building a software system is deciding precisely what to build, and no other part cripples the system as much if done wrong. Using a house-building analogy, adding a room late in construction is vastly more difficult and costly than changing the blueprint early on.
📐 Cost-to-Fix Principle: Correcting an error after development costs significantly more than fixing it earlier. Boehm (1981) reported this cost ratio as 68 times more; other studies suggest it can be as high as 200 times. 💡 Why this matters: This cost relationship makes sound requirements the most critical success factor for any project, as cost is directly tied to project success or failure.
3.3 Role of Requirements
The software requirements document plays a central role in the entire development process. In the project planning and feasibility phase, it is needed to determine the time and resources required to build the software, potentially leading to scope reduction. During the construction process, it serves as the base reference for designing and coding the software. Other activities like user documentation and testing also need this document for their deliverables. The project manager uses it to monitor and track progress and to change project scope through the change control process.
🔑 Definition — Change Control Process: The formal process for modifying the requirements document to change the scope of a project.
⭐ Key Takeaways
This lecture establishes requirement engineering as the most critical phase in software development. You must remember that it addresses the "what" of a system, not the "how," and that its primary output is the software requirements document. The most sobering fact is that 40-60% of all defects originate from poor requirements, and fixing these defects after development costs 68 to 200 times more than fixing them during the requirement phase. The requirements document serves as the central reference for project planning, design, coding, testing, and project management, making its accuracy and completeness vital to project success.
🧠 Quick Revision Questions
- In which phase of the software development lifecycle does requirement engineering primarily operate, and what is its core focus?
- List the four distinct phases of software development mentioned at the start of this lecture.
- According to the lecture, what percentage of all defects found in software projects can be traced back to poor requirements?
- What is the estimated cost ratio for fixing an error after development versus during the requirements phase, according to Boehm (1981)?
- What are the four different roles or activities that depend on the software requirements document as a central reference?
📘 Lecture 4 — Requirement Engineering-2
📖 Overview: This lecture examines the critical risks associated with inadequate requirements processes, including user dissatisfaction, budget overruns, and product failure. It then defines the different levels of software requirements—business, user, functional, and non-functional—explains stakeholder roles, and details the characteristics of high-quality requirement statement and specification documents.
🗂️ Topics Covered
The lecture begins by detailing six major risks from an inadequate requirement process: insufficient user involvement, creeping requirements, ambiguous requirements, gold-plating, minimal specifications, and incomplete requirements. It then introduces the four levels of software requirements (business, user, functional, and non-functional) with detailed examples, explains the crucial role of stakeholders, and contrasts the requirement statement document with the requirement specification document, listing the necessary characteristics for each.
📝 Lecture Summary
3.4 Some Risks from Inadequate Requirement Process
Requirements play the most significant role in software development, and the success or failure of a system depends largely on the quality of requirement documents. The lecture lists six key risks:
-
Insufficient user involvement leads to unacceptable products. If input from different types of users is not taken, the output lacks key functional areas, resulting in an unacceptable product. Overlooking the needs of certain user classes (stakeholders) leads to customer dissatisfaction.
-
Creeping user requirements contribute to overruns and degrade product quality. Requirement creep is one of the most significant factors in budget and time overruns, meaning identifying and adding new requirements at advanced stages of development.
-
Ambiguous requirements lead to ill-spent time and rework. Ambiguity means two different readers interpret the same requirement differently, arising from the imprecise nature of natural language. For example, the Urdu phrase “Rooko mut jane doo” can mean either “don’t let him go” or “let him go” depending on comma placement.
-
Gold-plating by developers and users adds unnecessary features. Gold-plating refers to features not in the original requirement document that the developer adds anyway, thinking they would add value, but resulting in schedule and budget overruns.
-
Minimal specifications lead to missing key requirements. For example, a requirement stated as “We need a flow control and source control engineering tool” resulted in a system with no print functionality, making it unusable. The example of a requirement stating average water level for a particular sensor does not specify how the system should respond if we try to calculate beyond the past six months.
🔑 Definition — Requirement Creep: identifying and adding new requirements to the list at some advanced stages of the software development process.
🔑 Definition — Ambiguity: two different readers of the same document interpret the requirement differently.
🔑 Definition — Gold-plating: features that are not present in the original requirement document and are not important for the end-user but the developer adds them anyway.
- Incompletely defined requirements make accurate project planning and tracking impossible.
💡 Why this matters: These risks directly cause project failures, budget overruns, and user dissatisfaction, making proper requirement engineering critical for success.
Levels of Software Requirements
Software requirements are defined at various levels of detail and granularity. Requirements at different levels serve different purposes.
-
Business Requirements: These state the high-level business objective of the organization or customer requesting the system. They document main system features and functionalities without going into nitty-gritty details, captured in a document describing the project vision and scope.
-
User Requirements: These add further detail to business requirements, written from a user’s perspective. They describe tasks the user must be able to accomplish to fulfill business requirements, captured in the requirement definition document.
-
Functional Requirements: The next level of detail brings in the system’s view and defines from the system’s perspective the software functionality developers must build into the product to enable users to accomplish their tasks.
-
Non-Functional Requirements: These describe constraints under which the system must operate, including external system interfaces, design and implementation constraints, quality and performance attributes, regulations, standards, and contracts. Non-functional requirements dictate how the system architecture and framework are built.
🔑 Definition — Non-Functional Requirements: constraints that are placed on the choices available to the developer for design and construction of the software product.
💡 Why this matters: All functional requirements must derive from user requirements, which must align with business requirements. During requirement engineering, focus on what and not how—requirements must not include design or implementation details.
Example: Word-Processing System with Spell Checker
To understand the difference between requirement types:
- Business requirement: User will be able to correct spelling errors in a document efficiently. Spell checker will be included as a feature.
- User requirement: Finding spelling errors in the document and decide whether to replace each misspelled word with one chosen from a list of suggested words.
- Functional requirement: The spell checker will find and highlight misspelled words, display a dialog box with suggested replacements, allow selection from the list, replace the misspelled word with the selected word, and allow global replacements.
- Non-functional requirement: It must be integrated into the existing word-processor that runs on windows platform.
Stakeholders
Stakeholders are different people who would be interested in the software. Management carries weight but is usually not actual users. Ignoring needs of any user class may result in system failure. Stakeholders tend to state requirements in general and vague terms, trivialize things, have sometimes conflicting requirements, and internal politics may influence requirements.
A study of over 8300 projects revealed the top two reasons for project failure are lack of user input and incomplete requirements.
🔑 Definition — Stakeholders: different people who would be interested in the software.
Requirement Statement and Requirement Specification Documents
Different levels of software requirements are documented in different documents. The two main documents are Requirement Statement (also called Requirement Definition) which documents user requirements, and Requirement Specification (also called Functional Specification) which documents functional requirements.
Requirement Statement Characteristics:
- Complete - Each requirement must fully describe the functionality to be delivered.
- Correct - Each requirement must accurately describe the functionality to be built.
- Feasible - It must be possible to implement each requirement within known capabilities and limitations.
- Necessary - Each requirement should document something the customer really needs or is required for conformance.
- Prioritized - An implementation priority must be assigned to each requirement.
- Unambiguous - All readers should arrive at a single, consistent interpretation.
- Verifiable - Users should be able to devise tests to determine proper implementation.
Requirement Specification Characteristics:
- Complete - No requirement or necessary information should be missing.
- Consistent - No requirement should conflict with other software or higher-level system or business requirements. Example: "All programs must be written in Ada" conflicted with "The program must fit in the memory of the embedded micro-controller" because Ada generated code was too large. Another example: "System must monitor all temperatures" conflicted with "System should only monitor temperatures below -20°C and above 400°C."
- Modifiable - One must be able to revise the SRS when necessary and maintain a history of changes.
- Traceable - One should be able to link each requirement to its origin, design elements, source code, and test cases.
Mixed Level of Abstraction
All requirements in a requirement document must be stated at a uniform level of abstraction. Differences in detail falsely imply relative importance and misguide development. Example violation:
- "The purpose of the system is to track the stock in a warehouse."
- "When a loading clerk types in the withdraw command he or she will communicate the order number, the identity of the item to be removed, and the quantity removed. The system will respond with a confirmation that the removal is allowable."
⭐ Key Takeaways
- An inadequate requirements process introduces six critical risks: insufficient user involvement, creeping requirements, ambiguous requirements, gold-plating, minimal specifications, and incomplete requirements—all leading to project failure and budget overruns.
- Software requirements exist at four distinct levels: business requirements (high-level objectives), user requirements (user tasks), functional requirements (system functionality), and non-functional requirements (constraints and quality attributes)—each documented in separate documents.
- Stakeholders are all people interested in the software; ignoring any user class can cause system failure, and the top reasons for project failure are lack of user input and incomplete requirements.
- A good requirement statement must be complete, correct, feasible, necessary, prioritized, unambiguous, and verifiable; a good requirement specification must be complete, consistent, modifiable, and traceable.
- Requirements must be written at a uniform level of abstraction to avoid misleading relative importance, and the focus must remain on what to build, not how to build it.
🧠 Quick Revision Questions
- What are the six risks from an inadequate requirement process, and how does each impact software development?
- Explain the difference between business requirements, user requirements, functional requirements, and non-functional requirements using the spell checker example.
- What is the difference between a Requirement Statement document and a Requirement Specification document, and what are the key characteristics of each?
- Why is consistency important in a requirement specification? Provide two examples of conflicting requirements from the lecture.
- What does "mixed level of abstraction" mean, and why is it a problem in requirement documents?
📘 Lecture 5 — Relationship of Several Components of Software Requirements
📖 Overview: This lecture explores the intricate relationships between various documents produced during the requirements engineering phase, focusing on how business requirements from different stakeholders can conflict and must be resolved. It introduces essential tools like the Vision Statement, Context Diagram, and Use Case Modeling for structuring and communicating software requirements effectively, emphasizing the need for domain understanding.
🗂️ Topics Covered
The lecture begins by examining Business Requirements and their potential conflicts among developers, retailers, and customers. It then covers the Vision Statement as a balanced guiding document, followed by Assumptions and Dependencies, Scope and initial release planning. The Context Diagram is introduced to graphically define system boundaries. Finally, the Use Case Model and its components—Actors and Use Cases—are explained as a key tool for capturing functional requirements and fostering the Customer-Developer Relationship.
📝 Lecture Summary
Relationship of Several components of Software Requirements
The lecture's core concept is the interconnected relationship between different documents produced during the requirements engineering phase. The provided figure illustrates how business requirements, the vision statement, scope, assumptions, and context diagrams all relate to each other. Conflicting goals from different stakeholders, such as a developer wanting high-tech features, a retailer wanting simple solutions, and a customer wanting convenience, must be resolved before detailing software requirements. Business requirements can also be used to set implementation priorities; for instance, a requirement to maximize revenue would prioritize features that directly drive sales.
🔑 Definition — Business Requirements: High-level objectives of the organization that requests or builds a system. These can often conflict, as seen with the kiosk example where the developer, retailer, and customer have different goals. These conflicts must be resolved before detailing software requirements.
📌 Example: For a kiosk product, the developer's business requirements include leasing the kiosk and selling consumables, while the retailer's include making money from customer use. A conflict arises because the developer wants a high-tech solution, while the retailer wants a simple one. These must be balanced to create a successful product.
The Vision Statement
The Vision Statement reflects a balanced view that satisfies the needs of diverse customers. It should be somewhat idealistic but grounded in realities like existing customer markets, enterprise architectures, organizational strategic directions, and resource limitations. It provides a high-level goal for the project.
📌 Example: The vision statement for the Chemical Tracking System states it will allow scientists to request chemicals, track their location and history, save 25% on chemical costs, and generate compliance reports for government regulations.
Assumptions and Dependencies
All assumptions made when conceiving the project must be recorded. These are factors believed to be true but not yet confirmed.
📌 Example: For the Chemical Tracking System, the management sponsor assumed it would replace the existing chemical stockroom inventory system and interface with the appropriate purchasing department applications.
Scope
Project scope defines the concept and range of the proposed solution, while limitations identify capabilities the product will not include. Clarifying scope helps establish realistic stakeholder expectations. Requirements that are out of scope must be rejected unless they are so beneficial that the scope should be enlarged (with accompanying budget, schedule, and staff changes). It is important to keep a record of rejected requirements as they tend to reappear.
Scope and Initial Release: The major features for the initial release should be summarized, along with the quality characteristics that will provide the intended benefits. Requirements must be prioritized and a release schedule created.
The Context Diagram
The Context Diagram graphically illustrates the boundary between the system and the outside world. It identifies external entities (terminators) and the flow of data and material between each entity and the system. It is used as the top-level abstraction in a dataflow diagram and can be included in the vision and scope document or the SRS.
🔑 Definition — Context Diagram: A graphical diagram that identifies the entities outside the system that interface with it and shows the flow of data and material between these external entities and the system itself.
📌 Example: The context diagram for the Chemical Tracking System shows external entities like "Scientist," "Chemical Stockroom," "Vendor," "Purchasing Department," "System Administrator," and "Government" interacting with the central system.
Use Case Model Components
A software engineer is typically hired to solve a domain problem, not a computer science one. To improve communication with the client, the engineer should learn domain-related terminology and use it in documenting requirements. The use case model is a tool for organizing and structuring requirements. It was developed by Ivar Jacobson and is now part of the Unified Modeling Language (UML) . It captures the discussion between developer and customer and is intuitive, even for those unfamiliar with UML.
🔑 Definition — Use Case: Specifies a complete functionality from its initiation by an actor until it has performed the requested functionality. 🔑 Definition — Actor: An entity (human, device, or system) that has an interest in interacting with the system.
The use case model:
- Represents a use case view of the system (how it is used).
- Treats the system as a black box, only depicting the external interface.
- Describes functional requirements from the end-user's perspective.
- Gives a clear description of what the system should do for the developer.
- Provides a basis for system testing and tracing functional requirements into actual classes and operations.
Use Cases and Customer-Developer Relationship
Excellent software products result from effective communication and coordination between developers and customers. To build this relationship and capture requirements properly, the requirement engineer must learn about the business that is to be automated. 💡 Why this matters: Without a strong customer-developer relationship, requirements can be misunderstood, leading to project failure.
🔑 Definition — Customer-Developer Relationship: A successful software project requires effective communication and coordination between developers and customers. The requirement engineer must learn the business domain to properly capture requirements.
⭐ Key Takeaways
This lecture highlights that software requirements engineering is a complex, multi-document process. The key for a software engineer is to master tools for resolving conflicts (like the Vision Statement), defining boundaries (like the Context Diagram), and capturing interactions (like Use Case Modeling). Critically, success hinges not on technical prowess alone but on building a strong customer-developer relationship through domain understanding and effective communication. Remember to document everything, including assumptions and out-of-scope requirements, to manage stakeholder expectations and prevent future misunderstandings. The Use Case Model is a powerful, intuitive tool for this, and mastering its components—Actors and Use Cases—is essential for any software professional.
🧠 Quick Revision Questions
- What three parties' conflicting requirements are highlighted in the business requirements section for the kiosk product, and what is the key to resolving their tension?
- What is the purpose of a Vision Statement, and what must it be balanced against?
- According to the lecture, why is it important to keep a record of rejected requirements?
- What is the primary purpose of a Context Diagram, and what does it graphically establish?
- What are the two main components of a Use Case Model, and what does each specify?
📘 Lecture 6 — Use Diagram for a Library System
📖 Overview: This lecture explains how to create and document use case models in software engineering. It covers the iterative process of identifying actors and use cases, defining relationships among use cases, elaborating use cases with detailed specifics, and visualizing them with activity diagrams. Understanding these concepts is crucial for capturing functional requirements and communicating system behavior from a user's perspective.
🗂️ Topics Covered
The lecture begins with an example use case diagram for a library management system, illustrating actors and use cases. It then describes the iterative process of creating a use case model. Next, it explains two types of relationships among use cases: "uses" and "extends", including actor inheritance. The process of elaborating use cases with components like preconditions, post-conditions, normal course of events, and exceptions is detailed. Alternative ways of documenting use cases are presented, followed by an explanation of activity diagrams for pictorial description. The lecture concludes by discussing the limitations of use cases, particularly regarding non-functional requirements.
📝 Lecture Summary
Use Diagram for a Library System
As an example, a use case diagram for a library management system is introduced. In this diagram, there are four actors: Book Borrower, Librarian, Browser, and Journal Borrower. These actors interact with eight use cases, which are represented by ovals enclosed within the system boundary, shown as a rectangle. It is important to note that every use case must always deliver some value to the actor. From the diagram, a Book Borrower can reserve a book, borrow a book, return a book, or extend loan of a book. Similarly, functions performed by other users can be easily examined.
Creating a Use Case Model
Creating a use case model is an iterative activity. The iteration starts with the identification of actors. In the next step, use cases for each actor are determined, which define the system. After that, relationships among use cases are defined. These steps are not strictly sequential; they are parallel and concurrent, and a use case model evolves slowly from these activities. The activity stops when no new use cases or actors are discovered. At the end, the model is validated.
3.9 Relationship among Use Cases
The UML allows extending and reusing already defined use cases by defining the relationship among them. Use cases can be reused and extended in two fashions: uses and extends.
In the case of a "uses" relationship, one use case invokes the steps defined in another use case during its own execution. This is similar to a function call. For example, the Delete Information use case uses two already existing use cases: Record Transaction and Cancel Transaction. The direction of the arrow determines which use case is using the other.
🔑 Definition — Uses relationship: A relationship where one use case invokes the steps defined in another use case during its own execution.
In the case of an "extends" relationship, it is a kind of generalization-specialization relationship. A special instance of an already existing use case is created. The new use case inherits all the properties of the existing use case, including its actors. For example, Place Conference Call is a specialization of Place Phone Call. In this case, the arrow goes from the new (derived) use case towards the base use case.
🔑 Definition — Extends relationship: A generalization-specialization relationship where a new use case inherits all properties of an existing use case.
💡 Why this matters: These relationships allow for reuse and extension of use cases, making the model more maintainable and less redundant.
Actor Inheritance
The concept of reusability can also be used for actors. New classes of actors may be created by inheriting from old classes. For example, Individual Customer and Corporate Customer are created by extending Customer. In this case, all the use cases available to Customer would also be available to these two new actors.
3.10 Elaborated Use Cases
After deriving the use case model, each use case is elaborated by adding detail of interaction between the user and the system. An elaborated use case has the following components:
- Use Case Name
- Implementation Priority: the relative implementation priority of the use case.
- Actors: names of the actors that use this use case.
- Summary: a brief description of the use case.
- Precondition: the condition that must be met before the use case can be invoked.
- Post-Condition: the state of the system after completion of the use case.
- Extend: the use case it extends, if any.
- Uses: the use case it uses, if any.
- Normal Course of Events: sequence of actions in the case of normal use.
- Alternative Path: deviations from the normal course.
- Exception: course of action in the case of some exceptional condition.
- Assumption: all the assumptions that have been taken for this use case.
As an example, the Delete Information use case is elaborated as follows:
- Use Case Name: Delete Information
- Priority: 3
- Actors: User
- Summary: Deleting information allows the user to permanently remove information from the system. Deleting information is only possible when the information has not been used in the system.
- Preconditions: Information was previously saved to the system and a user needs to permanently delete the information.
- Post-Conditions: The information is no longer available anywhere in the system.
- Uses: Record Transactions, Cancel Action
- Extends: None
- Normal Course of Events:
- The use case starts when the user wants to delete an entire set of information such as a user, commission plan, or group.
- The user selects the set of information that he/she would like to delete and directs the system to delete the information. - Exception 1, 2
- The system responds by asking the user to confirm deleting the information.
- The user confirms deletion. (Alternative Path: Cancel Action)
- A system responds by deleting the information and notifying the user that the information was deleted from the system.
- Uses: Record Transaction
- This use case ends.
- Alternative Path - The user does not confirm Deletion:
- If the user does not confirm deletion, the information does not delete.
- Uses: Cancel Action
- Exceptions:
- The system will not allow a user to delete information that is being used in the system.
- The system will not allow a user to delete another user that has subordinates.
- Assumptions:
- Deleting information covers a permanent deletion of an entire set of data such as a commission plan, user, group etc. Deleting a portion of an entire set constitutes modifying the set of data.
- Deleted information is not retained in the system.
- A user can only delete information that has not been used in the system.
📐 Structure: Elaborated use case components → provide a structured template for documenting all aspects of a use case's behavior.
3.11 Alternative Ways of Documenting the Use Case
Many people and organizations prefer to document the steps of interaction in two separate columns: User Action and System Reaction. This is a matter of personal and organizational preference. The important thing is to write the use case in proper detail.
📌 Example (Two-column format for Delete Information):
| User Action | System Reaction |
|---|---|
| 1. The use case starts when the user wants to delete an entire set of information such as a user, commission plan, or group. | |
| 2. The user selects the set of information that he/she would like to delete and directs the system to delete the information. - Exception 1, 2 | |
| 3. The system responds by asking the user to confirm deleting the information. | |
| 4. The user confirms deletion. | |
| 5. A system responds by deleting the information and notifying the user that the information was deleted from the system. |
3.12 Activity Diagrams
An activity diagram gives a pictorial description of the use case. It is similar to a flow chart and shows a flow from activity to activity. It expresses the dynamic aspect of the system. An activity diagram for the Delete Information use case is provided, showing activities like "Choose Object to Delete", "Initiate Deletion", decision diamonds for "[Delete Allowed]" and "[Confirm Delete]", and references to other activities (e.g., "See Activity Diagram for Canceling Actions").
🔑 Definition — Activity Diagram: A pictorial description of a use case, similar to a flow chart, that shows a flow from activity to activity and expresses the dynamic aspect of the system.
3.13 Limitations of Use Cases
Use cases alone are not sufficient. There are kinds of requirements (mostly non-functional) that need to be understood. Since use cases provide a user’s perspective, they describe the system as a black box and hide internal details. Hence, domain (business) rules as well as legal issues are not documented in a use case.
Non-functional requirements are also not documented in the use cases. Examples include:
- Usability: Color blind people should not have any difficulty in using the system – color coding should take care of common forms of color blindness.
- Reliability: The system needs to support 7 x 24 operation.
- Performance: Authorization should be completed within 1 minute 90% of the time. Average authorization confirmation time should not exceed 30 seconds.
- Portability: The system should run on Windows 98 and above as well as Sun Solaris 7.0 and above.
- Access: System should be accessible over the internet – hidden requirement – security.
💡 Why this matters: Because of this shortcoming, use cases must be augmented by additional information to capture all system requirements.
⭐ Key Takeaways
The most critical points from this lecture are that creating a use case model is an iterative activity involving actor identification, use case definition, and relationship modeling. Use cases can be related through "uses" (invoking another use case's steps) and "extends" (generalization-specialization) relationships, which also apply to actors. Each use case must be elaborated with detailed components like preconditions, post-conditions, normal and alternative flows, exceptions, and assumptions. While activity diagrams provide a pictorial flow of a use case, use cases alone have limitations in documenting non-functional requirements, domain rules, and legal issues, so they must be supplemented with additional information.
🧠 Quick Revision Questions
- What are the two types of relationships among use cases in UML, and what is the key difference between them?
- What are the essential components of an elaborated use case?
- In the "extends" relationship, what does the derived use case inherit from the base use case?
- What is the purpose of an activity diagram in relation to a use case?
- What are the main limitations of use cases, and what kind of requirements do they fail to capture?
📘 Lecture 7 — Source and Sink Analysis & Process Models
📖 Overview: This lecture introduces source and sink analysis as a verification technique to check completeness and consistency of requirements. It then explains process models as domain models used to understand business processes, with a detailed example of a hospital registration system. Understanding these concepts is critical for ensuring no redundant or missing requirements exist in software specifications.
🗂️ Topics Covered
This lecture covers source and sink analysis for verifying requirements completeness, including definitions and analysis of sources (origins of information) and sinks (consumers of information). It then shifts to domain models, emphasizing the importance of understanding the business domain as a software engineer. Finally, it introduces logical system models and provides a detailed business process model example of a hospital registration system, explaining the flow for both OPD and IPD patients.
📝 Lecture Summary
3.14 Source and Sink Analysis
Once requirements are documented using analysis models, an independent verification is needed to verify completeness and consistency. This involves careful analysis of sources and sinks of information.
🔑 Definition — Source: A source is a stakeholder who describes requirements (needs, constraints) to be included as system functionality. Sources can be processes that generate certain information that the system may have to process or maintain. Sources are the origins from where corresponding business processes are initiated. The analyst must trace from a requirement back to its origins to see who initiates it — be it a person, organization, or external entity.
🔑 Definition — Sink: A sink is the consumer of certain information. It provides a logical end to a business process. Sinks help identify persons, organizations, or external systems that receive functionality from the system. These are logical ends of requirements, or where all requirements are consumed.
📌 Example: Consider a user of a software application who retrieves a report from the system. When the user reviews the report, they become the sink of that report. The analyst analyzing the sink of a report requirement would naturally point toward the user who would receive that report.
In source and sink analysis, the analyst determines all sources of requirements and where these requirements are consumed (sinks). For a report displaying certain information, the source is the data (and who enters it) that is input to be retrieved later. Whoever needs this report becomes its sink.
At times, data is gathered in an application that is not used anywhere. The question becomes: is it redundant, or is something missing from the requirements? If certain inputs (sources) to a process have no corresponding outputs (sinks), such inputs are redundant and can be removed. However, if probing discovers corresponding outputs that were not recorded initially, those inputs were not redundant — rather, missing (output-related) requirements were discovered during sink analysis.
💡 Why this matters: A requirement statement describing a report but not listing its sources is incomplete. The software engineer validating such requirements must identify all sources against sinks (or vice versa) to determine complete end-to-end requirements.
Process Models
During the requirements analysis phase, different models are developed to express requirements. Though these models complement each other, they differ in how information is expressed. Most models are pictorial with explanatory diagrams.
Domain Models
Understanding the Business Domain
The first step in delivering a system is establishing what needs to be driven — clear understanding of the problem domain is imperative. A software developer must understand the business problem they are solving. Unless they develop this understanding, it is difficult to develop the right solution. Collecting both ends (sources, sinks) involved in different business processes ensures corresponding requirements are complete and yields better problem domain understanding.
A software engineer works on domains that may not correspond to their field of specialization. They may develop an embedded application for a microwave machine or a decision support system for a stock exchange broker. Since these underlying systems are not software systems, the software engineer cannot be expected to know these domains.
An important difference between software engineering and other engineering disciplines is that the software engineer works on problems not directly related to software engineering. An electrical engineer works on electrical domain problems; a civil engineer works on civil engineering problems. The software engineer must learn user vocabulary and terms used in routine operations. To overcome this, domain gathering techniques are used to extract requirements from unfamiliar systems, making requirements gathering and validation convenient and manageable.
4.2 Logical System Models
System models are techniques used to understand user needs, and software engineers use these to understand business domains. Software engineers develop diagrams to model different business processes. System models include:
- User business processes
- User activities for conducting business processes
- Processes that need to be automated
- Processes which are not to be automated
Business Process Model
The process model provides a high-level pictorial view of the business process. It can be used as a starting point to give basic orientation to the document reader. Below is an example of a hospital registration system which deals with two types of patients.
[Diagram Description: The business process diagram shows registration for both OPD (Out Patient Department) and IPD (In Patient Department) patients.]
As opposed to flow charts, there are parallel activities in this diagram which are further elaborated by specifying their major activities. The process described is as follows:
- A patient may come to visit In Patient Department (IPD) or Out Patient Department (OPD)
- System determines if they are a company patient or a private patient
- For a company patient, system verifies them
- For an OPD patient, system issues a chit to the patient and informs them about their number and consultant; the patient waits for their turn
- After verifying an IPD patient, system creates a visit and allocates a room or bed. If allocation fails, the patient is informed. Otherwise, the patient is checked in, and their information is maintained in the system
- System displays information about expenses of the required service to the patient
- Some advance payment is received against the required service, and this amount is adjusted in the final settlement
- All information is supplied to the cash office that deals with payments
- Upon receiving cash: for OPD patient, a chit is issued; for IPD patient, an admission form is filled, and information is maintained. A receipt is issued to the patient
- For credit transactions, corresponding vouchers are prepared
- The model depicts processes before treatment starts
- A patient may ask to change their service if unsatisfied; system cancels their record and pays their amount back
- A doctor may ask a patient to change their status from OPD to IPD
Important points about the business process diagram:
- It does not describe the automated system
- It only reflects the existing user process to help the software engineer/analyst understand the business domain
- It may contain information on processes that need not be automated
⭐ Key Takeaways
Source and sink analysis is a critical verification technique to ensure requirements completeness — every source must have a corresponding sink, and vice versa; finding unmatched pairs helps identify redundant inputs or missing output requirements. Understanding the business domain is essential for software engineers, who must learn user vocabulary and domain-specific terms since they often work on problems outside their direct expertise. Business process models provide high-level pictorial views of existing user processes, not automated systems, helping analysts understand the domain before designing solutions. The hospital registration example demonstrates that business processes can involve parallel activities (e.g., OPD vs IPD treatment paths) that must be modeled to capture all requirements correctly. System models include both automated and non-automated processes, and documenting them helps distinguish which parts need software support.
🧠 Quick Revision Questions
- What is the purpose of source and sink analysis in requirements verification?
- In the hospital registration example, what happens when a company patient visits IPD versus OPD?
- How can an analyst determine whether an input with no corresponding output is redundant or indicates missing requirements?
- Why must a software engineer learn user vocabulary when working on unfamiliar business domains?
- What are the key differences between a business process model and a flowchart?
📘 Lecture 8 — State Transition Diagrams
📖 Overview: This lecture introduces State Transition Diagrams (STDs) as a technique for documenting domain knowledge, particularly for systems where information moves through predefined states. It also covers the benefits of arranging information in tabular form and introduces Data Flow Models (DFDs) for capturing data transformation in automated systems. Understanding these modeling techniques is crucial for requirements analysis and system design.
🗂️ Topics Covered
The lecture covers State Transition Diagrams with an example of a trouble ticket life cycle, including six states (Queued, Open/Active, Deferred, Cleared, Closed, Disabled) and transitions. It then discusses arranging information in tabular form using examples from Function Point Analysis and Pakistan's Income Tax Ordinance. Finally, it introduces Data Flow Models, their notation (processes, external agents, data stores, data flows), the difference between DFDs and flowcharts, and a bank account management system example with guidelines for when to use DFDs.
📝 Lecture Summary
State Transition Diagrams
State Transition Diagrams (STDs) are a technique to document domain knowledge for systems where information flows from one place to another, with certain actions performed at each place. A file moving between desks in an office is a typical example, where movement is controlled by predefined rules. STDs document these rules clearly.
Trouble Ticket Life Cycle Example (from ITU-X.790) A "trouble" in a communications network is a problem that adversely affects service quality. When detected, a trouble report is entered by a user or raised automatically. Management of the trouble report ensures it receives attention and the trouble is cleared to restore service.
A trouble report also has a Trouble Status attribute that qualifies the state with finer granularity (e.g., "cleared awaiting customer verification"). The time of status attribute change is also captured.
A trouble report may go through six states:
Queued A trouble report is in a queued state when it has been instantiated but the trouble resolution process has not yet been initiated. It may be cancelled by the manager.
🔑 Definition — Queued: The state when a trouble report has been created but no action to resolve it has started.
Open/Active The trouble report becomes open/active when appropriate actions to resolve the trouble are initiated. It may be "referred" to another Hand-off Person or "transferred" to another Responsible Person while remaining in the open/active state. It may be cancelled by the manager.
🔑 Definition — Open/Active: The state when actions to resolve the trouble have started.
Deferred Deferred indicates corrective action has been postponed, such as when the faulty resource is inaccessible. A deferred report may become "open/active" again or move directly to "closed" if cancelled.
🔑 Definition — Deferred: The state when corrective action is postponed due to inaccessibility.
Cleared A trouble report moves to cleared when the agent determines the trouble has been resolved. Manager verification may optionally be awaited before closure.
🔑 Definition — Cleared: The state when the trouble has been resolved.
Closed Closed indicates the trouble resolution process is complete. Attributes are captured in a historical event, and the report may be eliminated at the agent's convenience, though records may be kept per business agreements.
🔑 Definition — Closed: The state when the trouble resolution process is complete and attributes are archived.
Disabled A disabled value occurs when a trouble report's information cannot be updated due to local conditions. Only read operations are permitted.
🔑 Definition — Disabled: The state when only read operations are allowed due to local conditions preventing updates.
The STD for a trouble ticket shows transitions such as: Create → Queued, Cancel → Closed, Approve + Open → Open/Active, Refer/Transfer (remains Open/Active), Defer → Deferred, Release → Open/Active, Clear → Cleared, Close → Closed, Delete → (removal), and Re-open → Open/Active.
💡 Why this matters: STDs make it easy to understand the complete lifecycle and movement rules of entities in a system, which is essential for designing correct workflows and validating business logic.
Arranging Information in Tabular Form
Sometimes information is more convenient to arrange in tabular form to make it easier to understand, design, code, and test. Two examples are presented:
Example 1: Function Point Analysis - Transactional Function Types Definitions from IFPUG CPM 4.1 for External Inputs, External Outputs, and External Inquiries are difficult to understand in prose form.
- External Input (EI): Processes data/control from outside the boundary; primary intent is to maintain ILFs and/or alter system behavior.
- External Output (EO): Sends data/control outside; primary intent is to present information using processing logic (at least one mathematical formula/calculation or derived data). May also maintain ILFs or alter behavior.
- External Inquiry (EQ): Sends data/control outside; primary intent is to present information by retrieving data from ILF or EIF. No formulas, calculations, derived data, ILF maintenance, or system behavior alteration.
The tabular form simplifies understanding:
Transactional Function Types Table
| Function | EI | EO | EQ |
|---|---|---|---|
| Alter the behaviour of the system | PI | M | N/A |
| Maintain one or more ILFs | PI | M | N/A |
| Present information to the user | M | PI | PI |
PI = Primary intent; M = May be; N/A = Not allowed
This table explains that if a function's primary intent is to present information only, it is an EQ. If it presents information but also maintains ILFs or alters behavior, it is an EO. If its primary intent is to maintain ILFs or alter behavior, it is an EI.
Example 2: Income Tax Ordinance of Pakistan 2001 The prose description of tax brackets is long and hard to follow. The tabular form makes it readable and easier to use:
Income Tax Table
| Income Range | Tax |
|---|---|
| Less than Rs. 60,000 | 0% |
| Between Rs. 60,000 and Rs. 150,000 | 7.5% of (Income - 60,000) |
| Between Rs. 150,000 and Rs. 300,000 | 12.5% of (Income - 150,000) + 6,750 |
| Between Rs. 300,000 and Rs. 400,000 | 20% of (Income - 300,000) + 25,500 |
| Between Rs. 400,000 and Rs. 700,000 | 25% of (Income - 400,000) + 45,500 |
| Greater than Rs. 700,000 | 35% of (Income - 700,000) + 120,500 |
💡 Why this matters: Once information is organized in tabular form, it can often be stored and mapped onto an array or database table, reducing programming to a table lookup. This reduces domain complexity, effort for design, coding, testing, and maintenance.
Data Flow Model
A Data Flow Model captures the flow of data in a system. It helps develop an understanding of system functionality by showing data sources, transformations, and final outputs. It describes data origination, transformation, and consumption, and organizes information at different levels of abstraction for top-down analysis.
The Notation
- Process (circle/rounded rectangle): Represents work to be done in the system; transforms data.
- External Agent (square): Represents external systems outside the boundary of this system.
- Data Store (open rectangle): Where data is stored for later retrieval; provides inputs to processes and receives outputs.
- Data Flow (arrow): Represents the movement of data in the diagram.
DFD versus Flow Charts DFDs show processes operating in parallel; looping and branching are typically not shown; each process path may have different timing. Flowcharts show sequential steps as an algorithm; looping and branching are part of flowcharts.
| DFD | Flow Chart |
|---|---|
| Processes can operate in parallel | Processes are sequential |
| Looping and branching not shown | Looping and branching are part of flowchart |
| Each path may have different timing | Shows sequence of steps as an algorithm |
Data Flow Model – Bank Account Management System Example
Processes:
- Reconcile account balance
- Deposit funds into an account
- Pay a bill
- Withdraw funds from an account
External Agents:
- Bank
- Creditor
- Employer
- Other income sources
Data Stores:
- Monthly Account statement
- Bank accounts
- Account transactions
Description: The "withdraw funds from an account" process retrieves account and transaction information, bank releases funds, and information goes to "reconcile account balance" which prepares a monthly statement. The "pay a bill" process has a creditor pay dues, accounts are updated, and a receipt is issued. The "deposit funds in an account" process has an employer deposit salaries into employee bank accounts; other income sources also deposit into accounts.
Data Flow Modeling Guidelines
- DFD captures data transformation between processes/functions, not control flow.
- Shows parallel activities without specific sequence.
- All previous models (business process, STD) capture business domain irrespective of automation.
- In DFDs, represent only processes that need automation (involve computation/processing/transformation).
- Processes that just move or transfer data without processing should not be modeled with DFDs.
- Example: A mail desk that just forwards mail has no processing; but if mail is noted in a register before delivery, that recording process can be automated and modeled with a DFD.
⭐ Key Takeaways
State Transition Diagrams are essential for documenting the lifecycle of entities that move through predefined states, such as trouble tickets. Arranging complex domain information in tabular form significantly improves readability, reduces complexity, and simplifies implementation by allowing table/dictionary lookups. Data Flow Models capture the transformation of data between processes that need automation, not control flow or manual transfer activities. The key distinction between DFDs and flowcharts is that DFDs show parallel business flows without sequencing, while flowcharts show sequential, algorithmic control flow. For the exam, remember the six trouble ticket states (Queued, Open/Active, Deferred, Cleared, Closed, Disabled), how to use the transactional function types table to classify EI/EO/EQ, and the DFD notation symbols.
🧠 Quick Revision Questions
- Name the six states of a trouble report and describe one transition that can occur from each state.
- In the IFPUG transactional function types table, what distinguishes an External Output (EO) from an External Inquiry (EQ)?
- What is the primary difference between a Data Flow Diagram and a Flow Chart?
- Why should processes that simply move or transfer data (without processing) not be modeled using a Data Flow Model?
- Using the income tax table, calculate the tax for a taxable income of Rs. 500,000.
📘 Lecture 9 — Typical Processes, Adding Levels of Abstraction to Data Flow Modeling, and Common Mistakes in Data Flow Diagrams
📖 Overview: This lecture explores typical processes modeled using data flow diagrams (DFDs), such as computation, decision-making, and data transformation. It then introduces the concept of adding levels of abstraction to DFDs—from context-level to detailed diagrams—using a Patient Monitoring System example. Finally, it covers common mistakes and illegal data flows to avoid when constructing DFDs, emphasizing source-sink analysis.
🗂️ Topics Covered
This lecture covers typical processes found in automated systems, including computation, decision-making, filtering, sorting, triggering, and CRUD operations. It explains how to add levels of abstraction to DFDs, starting with context-level diagrams and progressing to level 1 and level 2 diagrams, using a Patient Monitoring System example. The lecture also details common mistakes in DFDs, such as missing inputs or outputs, and illegal data flows like direct communication between external agents or data stores.
📝 Lecture Summary
4.3 Typical Processes
Processes in data flow diagrams transform data in various ways. Examples include computation processes like "Calculate Commission" which takes transaction amount and type as inputs. Decision-making processes determine outcomes, such as checking product availability in inventory. Filtering processes extract specific data, like sorting outstanding issues that are over a week old. Sorting processes organize data, such as using QuickSort on an array of numbers. Triggering processes invoke other functions, like monthly billing by utility companies. Finally, CRUD operations are actions performed on stored data: Create (stores new data), Read (retrieves data), Update (modifies existing data), and Delete (permanently removes data). 💡 Why this matters: Understanding these typical processes helps analysts identify and model core system functionalities systematically.
4.4 Adding Levels of Abstraction to Data Flow Modeling
To manage complexity, data flow modeling uses multiple levels of abstraction. The Context Level Data Flow Diagram (level 0) provides a high-level view of the system as a single process (a black box) interacting with external entities. It captures all external agents—persons, organizations, or other systems—and the information flows between them and the system, without showing internal details. For example, in a Patient Monitoring System, the context diagram shows the system interacting with a Patient (sending vital signs) and a Nurse (requesting reports, receiving warnings).
Detailed Data Flow Diagrams expand the context diagram. A level 1 DFD refines the single process into major sub-processes while keeping the same external entities. For the Patient Monitoring System, level 1 breaks the system into three processes: Local Monitoring (transforms vital signs into patient data), Central Monitoring (compares patient data with vital sign bounds and may generate a warning message), and Report Generator (handles nurse requests and retrieves log data from the Patient Log).
Level 2 DFDs further refine one process from level 1. For example, the Central Monitoring process in level 2 includes: Unpack Signs (separates patient data into pulse, temperature, and blood pressure), Evaluate Bounds Violation (compares these against vital sign bounds), Produce Warning Message (generates a warning if a violation occurs), and Format Patient Data (prepares formatted patient data for storage). A key rule is that the number of external agents, inputs, and outputs must remain consistent across all levels; adding or removing entities at any level makes the model inconsistent.
🔑 Definition — Context Level Data Flow Diagram: A high-level DFD that shows the entire system as a single process (black box) interacting with external entities, capturing all information flows but no internal details.
🔑 Definition — Level 1 Data Flow Diagram: A DFD that refines the context diagram by breaking the single process into major sub-processes, keeping the same external entities and data flows.
📐 Rule: The number of external agents, inputs, and outputs must be consistent across all levels of a DFD model (e.g., level 0, level 1, level 2). Any addition or removal of external entities or flows between levels is a mistake.
📌 Example: In the Patient Monitoring System, the context diagram shows two external entities (Patient and Nurse) with specific flows (vital signs, request for report, warning message, log data, report). Level 1 maintains these same entities and flows while adding three internal processes (Local Monitoring, Central Monitoring, Report Generator). Level 2 then refines Central Monitoring further, but the external entities and top-level flows remain unchanged.
4.5 Common Mistakes in Data Flow Diagrams
Common mistakes in DFDs are identified using source and sink analysis, which checks that every process has both an input (source) and an output (sink). Three key mistakes are highlighted using an accounting system example:
- Missing input: The process "Freeze Member Account" has no input arrow, meaning its source is unknown.
- Missing output: The process "Create a New Member Account" produces no output arrow, meaning its sink is not specified.
- Irrelevant inputs: The process "Generate an Employee Bank Statement" has two inputs (Employee Address and Employee Status), but neither is relevant to generating a bank statement (which requires an account number and time period).
Illegal Data Flows are also described:
- Directly Communicating External Agents: Two external entities (e.g., B1 and B2) communicating directly is illegal. A process must be inserted to transform and exchange data between them.
- External Agent Updating a Data Store Directly: An external agent (e.g., B1) updating a data store directly is illegal. A process must be used to receive, process, and store the data.
- External Agent Accessing a Data Store Directly: An external agent reading from a data store directly is illegal. A process must retrieve and pass the data to the agent.
- Copying Data Between Data Stores Directly: One data store copying data directly to another is illegal. A process must retrieve data from the source store, transform it, and store it in the target store.
🔑 Definition — Source and Sink Analysis: A technique to check completeness of requirements by evaluating whether every process has a defined source (input) and sink (output), ensuring no missing or irrelevant data flows.
📌 Example: In the accounting system DFD, the process "Freeze Member Account" has no input (source missing), "Create a New Member Account" has no output (sink missing), and "Generate an Employee Bank Statement" has irrelevant inputs (Employee Address and Employee Status, instead of account number and time period). Applying source-sink analysis reveals all three errors.
📌 Example of Illegal Flow: Two external entities (B1 and B2) shown with a direct arrow between them is illegal. Instead, a process like "Exchange Data Between External Agents" must be inserted.
⭐ Key Takeaways
For the exam, you must remember that typical processes in DFDs include computation, decision-making, filtering, sorting, triggering, and CRUD operations. DFDs use levels of abstraction: context-level (level 0) shows the system as a black box, level 1 breaks it into major processes, and level 2 or beyond refines individual processes. Always ensure consistency of external entities, inputs, and outputs across all levels. Apply source-sink analysis to check that every process has relevant inputs and outputs, and avoid illegal flows like direct communication between external agents, between external agents and data stores, or between data stores without an intermediate process.
🧠 Quick Revision Questions
- What are the four CRUD operations, and what does each one do to stored data?
- Explain the difference between a context-level DFD and a level 1 DFD. What remains unchanged between these two levels?
- In the Patient Monitoring System level 2 DFD, what are the four sub-processes of the Central Monitoring process, and what does each do?
- Using source-sink analysis, what three common mistakes can be identified in DFDs? Provide one example for each.
- List four types of illegal data flows in DFDs and explain why each is illegal.
📘 Lecture 10 — Prototyping and GUI Design
📖 Overview: This lecture addresses the controversial topic of including graphical user interface (GUI) details in the Software Requirements Specification (SRS) document. It explores both the motivations for using GUI sketches and the potential pitfalls, particularly when requirements are unstable. The lecture also introduces prototyping as a technique to reduce customer dissatisfaction and capture user vision early in the development process.
🗂️ Topics Covered
The lecture discusses the debate over including GUI details in SRS documents, the motivation for good GUI design, and the pitfalls of using GUIs in functional specifications. It provides a detailed example of GUI sketches for a "delete component" use case, highlighting common mistakes and the impact of unstable requirements. Finally, it introduces the concept of prototyping as a method to solidify understanding of requirements before full-scale development begins.
📝 Lecture Summary
GUI Sketches
Adding user interface details in the SRS is controversial. Opponents argue that by adding GUI details, focus shifts from what to how – GUI is part of the solution. On the other hand, many believe it is still what not how and should be part of the SRS. By adding GUIs in the functional specification (FS), requirements can be solidified with respect to scenario contents. The client often appreciates the SRS document more if it contains GUI details. The SRS is also the baseline for design, user manual, and test planning; presence of UI details allows these activities to start immediately after SRS acceptance. Rapid GUI drafting tools have made this task simpler. Exploring potential user interfaces helps refine requirements and makes user-system interaction more tangible. User displays can aid in project planning and estimation, and a user interface might highlight weaknesses in non-functional requirements like usability. However, if you cannot freeze the requirements specification until UI is complete, the requirement development process takes longer. A common mistake is using UI layouts as a substitute for defining functional requirements — they are supplementary information and cannot replace other SRS components. Any requirement change entails a UI change, and with unstable requirements, this means a lot of rework.
Motivation for GUI
- System users often judge a system by its interface rather than its functionality.
- A poorly designed interface can cause a user to make catastrophic errors.
- Poor user interface design is the reason why so many software systems are never used.
Pitfalls of using GUIs in Functional Specifications
- UIs distract from business process understanding (what) to interfacing details (how).
- Unstable requirements cause frequent modifications in UIs.
- An extra work to be done at the requirement level each time a GUI change must be incorporated.
Example: Delete Component Use Case
The following example demonstrates GUI sketches for a delete component use case and shows how unstable requirements cause difficulties.
The first GUI displays a drop-down list box containing component types, with a top entry of 'None'. The user clicks the arrow to select the component type whose component they want to delete.
The next GUI shows that the user has selected component type 'Plan Type'. Corresponding plans are populated and displayed in a list box on the right side of the GUI.
The following GUI depicts the scenario when user selects a particular plan 'Plan 3' and clicks on the 'Delete' button. If 'Plan 3' is currently being used, the application displays a dialog box informing the user that this plan cannot be deleted as it is in use.
The next GUI shows another dialog box where the user receives a message that 'Plan 3' is not in their hierarchy.
The user then selects 'Plan 2' and deletes it. The system confirms the deletion, and upon confirmation, deletes 'Plan 2'. After deleting, it displays a message that 'Plan 2' has been permanently deleted, yet 'Plan 2' is still visible in the list.
🔑 Definition — Key Mistakes: The above GUIs present two major mistakes. First, if a plan is currently in use, it should not have been displayed in the list at all. Second, instead of displaying two messages separately in two dialog boxes, it would have been appropriate to combine them into one message.
The corrected GUI shows that since the user can only delete plans 1 and 2, only those plans should be displayed to them.
📌 Example: In this example, it is evident that if requirements are partially generated, a number of changes have to be made. Sometimes the frequency of these changes rises so much that it takes all of the requirements and design time just in finalizing GUIs.
💡 Why this matters: This demonstrates that unstable requirements cause excessive rework on GUIs, wasting valuable development time and potentially derailing the entire project schedule.
Prototype
Prototyping is a technique used to reduce customer dissatisfaction at the requirement stage. The idea is to capture the user's vision of the product and get early feedback from the user to ensure the development team understands the requirements. This is used when there is uncertainty regarding requirements. Sometimes, even the customer does not know what they actually need, which happens when there is no manual solution.
🔑 Definition — Prototype: A prototype is not the real product. It is a real-looking mock-up of what would eventually be delivered and might not do anything useful. However, the presence of a prototype makes a new product tangible. It brings use cases to life and closes gaps in your understanding of the requirements. From a user's perspective, it is easier to play with a prototype and try it out than to read an SRS document.
⭐ Key Takeaways
The key lesson from this lecture is that while GUI sketches and prototypes are valuable tools for solidifying requirements and gaining user feedback, they must be used carefully. GUIs should supplement, not replace, functional requirements in the SRS. Unstable requirements can cause excessive rework on GUIs, consuming valuable development time. Prototyping is most effective when there is uncertainty about requirements, as it makes the product tangible for users and helps close gaps in understanding. The most critical takeaway is that GUI design mistakes—like displaying items that cannot be deleted or showing redundant error messages—can be avoided by thoroughly understanding requirements before designing the interface.
🧠 Quick Revision Questions
- What are the two main arguments for and against including GUI details in the SRS document?
- What are the three pitfalls of using GUIs in functional specifications as described in the lecture?
- In the delete component example, what two major mistakes were made in the initial GUI designs?
- What is a prototype, and when is prototyping most useful according to the lecture?
- Why is it easier for users to interact with a prototype than to read an SRS document?
📘 Lecture 11 — Software Design
📖 Overview: This lecture introduces the software design phase, where the focus shifts from requirements (what) to implementation (how). It covers strategies for managing complexity, fundamental design approaches (structured vs. object-oriented), and the qualities that define a good, maintainable software design.
🗂️ Topics Covered
The lecture covers the introduction to software design as the phase where system structure is modeled, including data models, components, and interfaces. It explains managing complexity through separation of concerns, modularity, and abstraction. The software design process is described as iterative, involving multiple models at different abstraction levels. Two fundamental design strategies are compared: functional (structured) and object-oriented design. Finally, the qualities of software design are discussed, with a focus on maintainability, cohesion, and loose coupling.
📝 Lecture Summary
6.1 Introduction
Once requirements are established, the design phase shifts focus from what to how. The objective is to analyze and understand the system in detail to identify and document features and components of at least one feasible solution. The design activity provides a roadmap to progressively transform requirements into the final product by describing the system's structure to be implemented.
This includes modeling data structures and entities, the physical and logical partitioning of the system into components, and the interfaces between different components as well as to the outside world. Sometimes, design of algorithms is also included.
🔑 Definition — Software Design: The process of analyzing and understanding a system in detail so that features and constituent components of at least one feasible solution are identified and documented, providing a roadmap for implementation.
6.2 Managing Complexity of a Software System
A complex system that works is invariably found to have evolved from a simple system that worked. We understand only those systems that have a hierarchical structure and where intra-component linkages are generally stronger than inter-component linkages. To manage complexity, we apply the principles of separation of concern, modularity, and abstraction.
Separation of concern allows us to deal with different individual aspects of a problem in isolation, independent of each other.
Modularity is the classic divide-and-conquer philosophy: a complex system is divided into smaller pieces of lesser complexity called modules. One major advantage is that it allows the designer to apply separation of concern on individual modules.
💡 Why this matters: These principles lead to designs that are easy to understand and hence easy to maintain.
🔑 Definition — Separation of Concern: A design principle that allows dealing with different individual aspects of a problem by considering these aspects in isolation and independent of each other. 🔑 Definition — Modularity: The division of a complex system into smaller pieces (modules) of lesser complexity, following the divide-and-conquer philosophy.
Software Design Process
Software design is not a sequential process; it evolves through a number of iterations. The process usually involves developing several different models, looking at the system from different angles and describing it at various levels of abstraction. These models complement each other, much like the models used during requirement engineering.
Activities at this stage include:
- Design of the software architecture showing division into sub-systems or modules
- Specification of services provided by sub-systems and their interfaces
- Division of each sub-system into smaller components with their own services and interfaces
- Data modeling including identification of data entities, their attributes, relationships, and appropriate data structures
Software Design Strategies
The design process revolves around decomposing the system into smaller units and then systematically integrating them. Two fundamental strategies are used:
Functional or Structured Design: The structure revolves around functions. The entire system is abstracted as a main function that is decomposed into smaller functions. The main function delegates responsibilities to these smaller functions and makes calls to them. The process continues until functions are at a level of granularity where they can be easily implemented. The system state (data) is centralized and shared by all functions.
Object-Oriented Design: The system is decomposed into a set of objects that cooperate and coordinate with each other. The system state is decentralized, and each object is responsible for maintaining its own state. Communication and coordination are achieved through message passing, where one object requests services from another object.
The object-oriented approach has gained popularity over the structured design approach because, in general, it yields a design that is more maintainable than the one produced by the functional approach.
🔑 Definition — Functional Design: A design strategy where the system structure revolves around functions, with a centralized system state shared by all functions. 🔑 Definition — Object-Oriented Design: A design strategy where the system is decomposed into objects with decentralized state, communicating through message passing.
Software Design Qualities
A software design can be measured and analyzed using different parameters:
- Efficiency
- Compactness
- Reusability
- Maintainability
A good design from one perspective may not be suitable from another. For example, an efficient and compact design may not be easy to maintain. The project and application requirements determine quality priorities. An embedded system for a nuclear reactor may prioritize efficiency, while a business system would prioritize maintainability.
Maintainable Design
Since maintenance contributes to a major share of overall software cost, the objective in most cases is to produce a system that is easy to maintain. A maintainable design minimizes the cost of system change and is flexible enough to easily modify existing functionality and add new functionality.
To achieve maintainability, the design should be understandable and changes should be local in effect — a change in one part should not affect other parts. This is achieved by applying the principles of modularity, abstraction, and separation of concern. When applied properly, these principles yield a design that is more cohesive and loosely coupled, and thus easy to maintain.
🔑 Definition — Maintainable Design: A design where the cost of system change is minimal and the system is flexible enough to be easily adapted to modify existing functionality and add new functionality. 🔑 Definition — Cohesion: A measure of how strongly related the elements within a module are to each other (higher cohesion is better). 🔑 Definition — Coupling: A measure of the degree of interdependence between modules (loose coupling is better).
⭐ Key Takeaways
The software design phase shifts focus from what the system should do to how it will be built, providing a roadmap for implementation through iterative modeling. To manage complexity, designers must apply the principles of separation of concern, modularity, and abstraction, which lead to hierarchical structures where intra-component linkages are stronger than inter-component linkages. Two fundamental design strategies exist: functional design with centralized data and object-oriented design with decentralized data and message passing, with the latter generally producing more maintainable designs. Maintainability is typically the primary design goal because it accounts for the largest share of software cost, achieved when designs are understandable and changes have local effects. A maintainable design is characterized by high cohesion within modules and loose coupling between modules, resulting from proper application of the core design principles.
🧠 Quick Revision Questions
- What is the fundamental shift in focus that occurs when moving from requirements engineering to the software design phase?
- What three principles are applied to manage the complexity of a software system, and how does each contribute to better design?
- How do functional (structured) design and object-oriented design differ in their approach to system state and inter-component communication?
- Why is maintainability typically the primary quality objective in software design, and what two characteristics make a design maintainable?
- What do the terms "cohesion" and "coupling" mean in the context of software design, and what values of each indicate a good design?
📘 Lecture 12 — Coupling and Cohesion
📖 Overview: This lecture explores two critical software design concepts: coupling and cohesion, which measure the independence and internal consistency of modules. Understanding these principles helps engineers create modular, maintainable, and reusable software. The lecture also covers abstraction, encapsulation, and contrasts function-oriented vs. object-oriented design approaches.
🗂️ Topics Covered
The lecture covers definitions and measures of coupling and cohesion, their graphical representation, and detailed examples demonstrating low vs. high coupling using a vector class and low vs. high cohesion using an order class. It then introduces abstraction and encapsulation with a sorting algorithm example, and concludes with a comparison of function-oriented versus object-oriented design.
📝 Lecture Summary
6.3 Coupling and Cohesion
Coupling is a measure of the independence of a module or component. Loose coupling means different system components have less reliance upon each other, so changes in one component have a limited effect on others. Strong cohesion implies that all parts of a component should have a close logical relationship with each other, meaning all related pieces are found in one place when changes are required.
A component should implement a single concept or a single logical entity. All parts of a component should be related to each other and necessary for implementing that component. If a component includes unrelated parts, it is said to have low cohesion.
Coupling and cohesion are contrasting concepts but indirectly related. Cohesion is an internal property of a module (intra-component linkages), while coupling is its relationship with other modules (inter-component linkages). If modules are more independent, they will be less dependent upon others. Therefore, a highly cohesive system also implies less coupling.
A good example of a system with very high cohesion and very low (almost nil) coupling is the electric subsystem of a house made up of electrical appliances and wires. Each appliance has a clearly definable function completely encapsulated within it, meaning an appliance does not depend upon any other for its function. However, adding a centralized control unit to control appliances according to certain settings creates more coupling.
Modules with high cohesion and low coupling can be treated and analyzed as black boxes, allowing us to analyze them independently by applying the principle of separation of concern.
🔑 Definition — Coupling: A measure of the interdependence of two modules. 🔑 Definition — Cohesion: A measure of the independence of a module's internal parts. 🔑 Definition — Separation of Concern: The principle of analyzing modules independent of other modules.
Coupling and cohesion can be represented graphically. In a highly coupled system, module boundaries are not well defined, as everything seems connected to everything else through shared data. In a low coupling system, module boundaries are well defined, intra-component linkages are stronger while inter-component linkages are weak.
📌 Example of Coupling: Modules that interact through message passing have low coupling, while those interacting through variables that maintain state information have high coupling.
Consider a vector class with public data members:
class vector {
public:
float x;
float y;
vector (float x, float y);
float getX();
float getY();
float getMagnitude();
float getAngle();
};
A function to calculate dot product can be written using the public interface (loose coupling):
float myDotProduct1(vector a, vector b) {
float temp1 = a.getX() * b.getX();
float temp2 = a.getY() * b.getY();
return temp1 + temp2;
}
Or directly using public data members (tight coupling):
float myDotProduct2(vector a, vector b) {
float temp1 = a.x * b.x;
float temp2 = a.y * b.y;
return temp1 + temp2;
}
If the class designer changes the implementation to store magnitude and angle instead of x and y:
class vector {
public:
float magnitude;
float angle;
// ... methods remain the same
};
The first version (myDotProduct1) using the public interface requires no change because the system was loosely coupled. The second version (myDotProduct2) must be rewritten because it had more dependency on the internal structure and hence more coupling.
💡 Why this matters: This example demonstrates how tight coupling creates ripple effects when implementation details change, making maintenance costly and error-prone.
📌 Example of Cohesion: A class is cohesive if most of the methods defined in the class use most of the data members most of the time. If different subsets of data are manipulated by separate groups of functions, the class is not cohesive and should be broken down.
Consider an order class mixing order and customer information:
class order {
public:
int getOrderID();
date getOrderDate();
float getTotalPrice();
int getCustomerId();
string getCustomerName();
string getCustomerAddress();
int getCustomerPhone();
// ... setters for all
private:
int orderId;
date orderDate;
float totalPrice;
item lineItems[20];
int customerId;
string customerName;
int customerPhone;
int customerFax;
};
This class is not cohesive because it contains information about both the order and the customer, which are distinct entities. It must be broken into two separate, more cohesive classes:
class order {
public:
int getOrderID();
date getOrderDate();
float getTotalPrice();
int getCustomerId();
void setOrderID(int oId);
void setOrderDate(date oDate);
void setTotalPrice(float tPrice);
void setCustomerId(int cId);
void addLineItem(item anItem);
private:
int orderId;
date orderDate;
float totalPrice;
item lineItems[20];
int customerId;
};
class customer {
public:
int getCustomerId();
string getCustomerName();
string getCustomerAddress();
int getCustomerPhone();
int getCustomerFax();
// ... setters
private:
int customerId;
string customerName;
int customerPhone;
int customerFax;
};
6.4 Abstraction and Encapsulation
Abstraction is a technique where we construct a model of an entity based upon its essential characteristics and ignore the inessential details. The principle of abstraction helps handle the inherent complexity of a system by allowing us to look at important external characteristics while hiding inner complexity. Encapsulation is hiding the internal details. Abstraction is a special case of separation of concern, where we separate the concern of users who only need to understand the external interface without bothering about actual implementation.
🔑 Definition — Abstraction: A technique of modeling an entity based on its essential characteristics, ignoring inessential details. 🔑 Definition — Encapsulation: Hiding the internal details of a component.
📌 Example: A selectionSort function can be rewritten by abstracting logical steps into auxiliary functions. The original function:
void selectionSort(int a[], int size) {
int i, j, min, temp;
for(i = 0; i < size –1; i++) {
min = i;
for (j = i; j < size; j++) {
if (a[j] < a[min])
min = j;
}
temp = a[i];
a[i] = a[min];
a[min] = temp;
}
}
By abstracting out swapping and finding the minimum value:
void swap(int &x, int &y) {
int temp;
temp = x;
x = y;
y = temp;
}
int indexOfMinimumValue(int a[], int from, int to) {
int i, min;
min = from;
for (i = from+1; i < to; i++)
if (a[i] < a[min]) min = i;
return min;
}
void selectionSort(int a[], int size) {
int i, min;
for (i = 0; i < size; i++) {
min = indexOfMinimumValue(a, i, size);
swap(a[i], a[min]);
}
}
The resultant function is easier to understand. As a by-product, we created two general-purpose reusable functions. The principle of abstraction thus generates reusable self-contained components.
6.5 Function Oriented versus Object Oriented Design
In the action-oriented (function-oriented) approach, data is decomposed according to functionality requirements; decomposition revolves around function. In the OO approach, decomposition revolves around data (objects). The action-oriented paradigm focuses only on functionality, typically ignoring data until required. The OO paradigm focuses on both functionality and data simultaneously.
The basic difference is centralized control mechanism (action-oriented) versus decentralized control mechanism (OO). Decentralization gives OO the ability to handle essential complexity better.
🔑 Definition — Action-Oriented Design: An approach where decomposition revolves around functions, and data is managed separately. 🔑 Definition — Object-Oriented Design: An approach where decomposition revolves around data (objects), and relevant data and functionality are kept together.
In action-oriented design, function knows about the data it uses, but data does not know about the functions using it. This means changing a function is easy (you know which data is affected), but changing a data structure is difficult (hard to find all functions using that data). Object-oriented approach solves this by putting relevant data and functionality together at one place. In case of change, affected components can be identified easily, and the effect is localized. Data is not shared; anyone needing information sends a message through the object's interface. This creates highly cohesive objects by keeping related data and function together and spinning-off non-related information into other classes.
⭐ Key Takeaways
A student must remember that cohesion measures internal consistency within a module while coupling measures interdependence between modules; high cohesion implies low coupling. The core principle is that components should implement a single logical entity with all parts being necessary and related. When changes are required, tightly coupled systems cause ripple effects, as shown in the vector class example where accessing public data members directly caused rewriting when implementation changed. Abstraction and encapsulation are key techniques for managing complexity by hiding internal details and exposing only essential interfaces. Finally, object-oriented design offers advantages over function-oriented design by localizing the impact of changes and creating decentralized control through highly cohesive objects.
🧠 Quick Revision Questions
- What is the difference between coupling and cohesion, and how are they related?
- In the vector class example, why did
myDotProduct2need to be rewritten whilemyDotProduct1did not? - What makes a class non-cohesive, and how should it be fixed? Use the order class example.
- How does abstraction lead to reusable components, and what is the difference between abstraction and encapsulation?
- What is the fundamental difference between action-oriented and object-oriented design in terms where data and functions are placed?
📘 Lecture 13 — Object Oriented Analysis and Design
📖 Overview: This lecture introduces Object-Oriented (OO) technology and explains why it evolved to bridge the gap between real-life objects and their software counterparts. It covers the fundamental components of OO design, including objects, classes, classification, and the object model, and provides a detailed comparison of inter-object relationships—particularly association versus aggregation—with conceptual and implementation differences.
🗂️ Topics Covered
The lecture begins with an explanation of why object-oriented design is necessary, contrasting it with function-oriented approaches. It then defines the basic OO components: objects and classes. Classification of objects is discussed with examples. The object model is presented, covering abstraction, encapsulation, and hierarchy. Finally, the three inter-object relationships (inheritance, association, and aggregation) are explored in depth, with a detailed comparison of association and aggregation across multiple dimensions.
📝 Lecture Summary
Object Oriented Design - Why?
Software models real-life entities and processes. Traditional approaches treated software as separate information and procedures without explicit relationships, hiding the mapping between software components and real-world objects. Object-oriented technology evolved to bridge this gap by encapsulating data and processes related to a real-life object into a single software entity. It also allows objects to inherit properties from ancestors, similar to real-life inheritance.
A complex system that works evolved from a simple system that worked. Hierarchical structure with stronger intra-component linkages than inter-component linkages leads to loose coupling, high cohesion, and better maintainability. An OO system consists of objects that are hierarchical, highly cohesive, and loosely coupled.
Key advantages of OO technology include:
- Clarity and understandability—closer to human cognition
- Reusability—from low interdependence and inheritance
- Reduced maintenance effort—from inheritance, encapsulation, low coupling, and high cohesion
🔑 Definition — Function-oriented (action-oriented) approach: Data is decomposed according to functionality requirements; decomposition revolves around function. 🔑 Definition — Object-oriented approach: Decomposition revolves around data; focuses on both functionality and data simultaneously. It uses decentralized control as opposed to centralized control in action-oriented approach.
📌 Example: In a function-oriented approach, functions know about the data they use, but data does not know about functions using it. Changing a function is easy because affected data components are known. However, changing a data structure is difficult because all functions using that data must be found and modified. In OO, since data and function are encapsulated in one class, the effect of change is localized, making maintenance easier.
Object Oriented Design Components - What?
The Object and the Class
The basic unit of OO design is an object. An object is a tangible entity that exhibits well-defined behavior. It represents an individual, identifiable item, unit, or entity—real or abstract—with a defined role in the problem domain. An object has state, behavior, and identity.
- State: All properties of the object and their current values. Properties are usually static. State is encapsulated within the object.
- Behavior: How an object acts and reacts in terms of state changes and message passing. A message is an action one object performs upon another to elicit a reaction. Operations clients may perform are called methods.
- Identity: The unique existence of an object.
A class defines the structure and behavior of similar objects. A class represents an abstraction—the essence or template of an object. It specifies an interface (outside view, public part) and defines an implementation (inside view, private part). The interface contains declarations of all operations applicable to instances of the class; the implementation contains the actual code for those operations.
Classification
Classification is the most important and critical stage in OOA and OOD—appropriate grouping of objects into classes. Proper classification requires looking at the problem from different angles. The same object can be classified into different categories depending on perspective.
📌 Example: A horse can be classified based on:
- Data-driven: head, tail, body, leg
- Behavior-driven: walk, run, eat
- Responsibility-driven: carry things, communicate, maintain its living system
The Object Model
The elements of OO design collectively form the Object Model, which encompasses the principles of abstraction, encapsulation, and hierarchy (inheritance).
- Abstraction: A powerful technique for dealing with complexity by ignoring essential details and dealing with a generalized, idealized model. It focuses on the outside view, separating external behavior from implementation. Deciding the right set of abstractions is the central problem in OO design.
- Encapsulation: Hides implementation details of an object. Abstraction and encapsulation are complementary—abstraction provides the outside view, encapsulation prevents clients from seeing the inside view. Intelligent encapsulation localizes design decisions likely to change. The essential benefit: changing an object's representation without disturbing clients.
💡 Why this matters: Abstraction and encapsulation together allow developers to manage complexity by focusing on what an object does (interface) rather than how it does it (implementation), enabling modularity and easier maintenance.
Relationship Among Objects
The object model presents a static view of the system and illustrates how objects collaborate. Three inter-object relationships are specified:
- Inheritance: Defines a "kind of" hierarchy (generalization/specialization). A subclass shares structure and behavior defined in a superclass. A subclass augments or redefines existing structure and behavior. Identifying hierarchy requires discovering patterns among many objects.
- Association: When object A "uses" object B, A may send messages to B. This defines visibility among objects.
- Aggregation: Defines "part-of" structure. When object A is part of the state of object B, A is contained by B. Aggregation reduces the number of visible objects at the enclosing level but may lead to tighter coupling.
Aggregation and Association - Conceptual and Implementation Issues and Differences
Association and Aggregation - Some basic differences
Objects collaborate in many ways to achieve goals. The three relationship types are:
- Inheritance: "kind of" relationship
- Aggregation: "part of" relationship
- Association: some semantic connection among otherwise unrelated classes
Aggregation is the "part-whole" or "a-part-of" relationship where components are encapsulated within an assembly. The whole is meaningless without its parts, and parts cannot exist without the container. Properties of the assembly may propagate to components. Aggregation implies tighter coupling than association.
🔑 Definition — Aggregation vs. Association (basic rule): If two objects are tightly coupled and cannot exist independently, it is aggregation. If they are usually independent, it is association.
Object Creation and Life Time
When an object (the whole) is instantiated, all its parts must also be instantiated at the same time before useful work can be done. All parts die with the whole. In association, the lifetime of two associated objects is independent—the only limitation is that an object must be alive before a message can be sent to it.
Coupling and Linkages
Aggregation implies much tighter coupling than association. The links between whole and part are permanent in aggregation. In association, links may be maintained only for the period an object requires services of its associated object and may be disconnected afterward.
Ownership and visibility
In aggregation, since the whole contains the part, the part is encapsulated or hidden within the whole and is not accessible from outside. Only the whole can send messages to its parts. The whole owns its parts, and the part becomes a private property of the whole—other objects do not need to know about its existence. In association, the associated object may be shared among many objects—many objects may hold a reference to the same object simultaneously.
🔑 Definition — Ownership: In aggregation, the whole owns its parts (private). In association, objects are shared (public reference).
Database persistence
When an object is persisted (stored) in a database, all its components (all parts of the whole) must also be persisted in their entirety along with the whole for future reference. For association, only a reference to the associated object may be stored in the database. A normalized database enforces this restriction.
⭐ Key Takeaways
Object-oriented design emerged to bridge the gap between real-world entities and software by encapsulating data and behavior into objects, promoting clarity, reusability, and maintainability. The fundamental building blocks are objects (with state, behavior, and identity) and classes (templates defining interface and implementation). The object model rests on three principles: abstraction (focusing on outside view), encapsulation (hiding implementation), and hierarchy/inheritance (defining generalization-specialization relationships). Understanding the difference between association (loose, independent, shareable, temporary links) and aggregation (tight, part-whole, ownership, permanent links with dependent lifetimes) is critical for proper OO design. The key distinguishing factor across all dimensions is coupling—aggregation implies tighter coupling than association.
🧠 Quick Revision Questions
- What are the three main advantages of object-oriented technology over other approaches?
- How does the concept of "decentralized control" differ between function-oriented and object-oriented approaches?
- Define and distinguish between an object and a class in OO design.
- What are the three principles encompassed by the object model, and explain each briefly.
- List four ways to differentiate between association and aggregation relationships.
📘 Lecture 14 — Object Oriented Design
📖 Overview: This lecture explores the process of transforming an analysis model into a design model using Object-Oriented Design (OOD). It introduces the four-layer OOD pyramid and details Object-Oriented Analysis (OOA) techniques, with a focus on Abbot’s Textual Analysis for identifying classes and their components from problem statements. Understanding this translation is crucial for creating a structured blueprint for software construction.
🗂️ Topics Covered
The lecture covers the four layers of the Object-Oriented Design pyramid: subsystem, class and object, message, and responsibility layers. It then explains the translation from the analysis model to the design model. The focus shifts to Object-Oriented Analysis, including tasks for static and dynamic modeling. Finally, the lecture details Abbot’s Textual Analysis technique, using parts of speech to identify model components and an example of a cash register to practice identifying and eliminating classes.
📝 Lecture Summary
Object Oriented Design
Object-Oriented Design (OOD) transforms the analysis model into a design model that serves as a blueprint for software construction. OOD results in a design that achieves a number of different levels of modularity. The four layers of the OO design pyramid are:
- The subsystem layer. Contains a representation of each of the subsystems that enable the software to achieve its customers defined requirements and to implement the technical infrastructure that supports customer requirements.
- The class and object layer. Contains the class hierarchies that enable the system to be created using generalization and increasingly more targeted specializations. The layer also contains design representations for each object.
- The message layer. Contains the details that enable each object to communicate with its collaborators. This layer establishes the external and internal interfaces for the system.
- The responsibility layer. Contains the data structures and algorithmic design for all attributes and operations for each object.
💡 Why this matters: Understanding these four layers ensures that the design covers all critical aspects of a software system, from high-level subsystems to low-level data structures and communication protocols.
Translating the analysis model into a design model during object design
The lecture presents a diagram showing the translation from an Analysis Model (containing classes, attributes, methods, relationships, behavior) to a Design Model (containing objects, data structures, algorithms, messaging, control). This translation is the core activity of OOD.
🔑 Definition — OOD: The process of transforming the analysis model into a design model that serves as a blueprint for software construction.
Object Oriented Analysis
The intent of Object-Oriented Analysis (OOA) is to define all classes, their relationships, and their behavior. A number of tasks must occur:
- Static Model a) Identify classes (i.e. attributes and methods are defined) b) Specify class hierarchy c) Identify object-to-object relationships d) Model the object behavior
- Dynamic Model a) Scenario Diagrams
🔑 Definition — OOA: The process of defining all classes, their relationships, and their behavior.
Object-Oriented Analysis using Abbot’s Textual Analysis
The first object-orientation technique studied is one of the oldest techniques to identify objects and their relationships: Textual Analysis. It was initially developed by Abbot and then extended by Graham and others. In this technique, different parts of speech are identified within the text of the specification, and these parts are modeled using different components.
| Part of speech | Model component | Example |
|---|---|---|
| proper noun | instance | Mehdi Hassan |
| improper noun | class/type/role | student, teacher |
| doing verb | operation | buy |
| being verb | classification | is a horse, is a book |
| having verb | composition | fan has wings |
| adjective | attribute value or class | this ball is green |
| adjective phrase | association | the customer with children, the customer who bought the kite |
Once all the model components have been identified, we will eliminate the redundant or irrelevant components by again analyzing the text and the context of the problem.
Let’s now try to understand this with the help of an example:
Problem Statement: A simple cash register has a display, an electronic wire with a plug, and a numeric keypad, which has keys for subtotal, tax, and total. This cash storage device has a total key, which triggers the release on the drawer. The numeric buttons simply place a number on the display screen, the subtotal displays the current total, the tax key computes the tax, and the total key adds the subtotal to the tax.
Our task now is to:
- Identify all the classes in this problem statement.
- Eliminate the unnecessary classes.
We are now going to use nouns to find classes.
Nouns (initial) Register, Display, Wire, Plug, Keypad, Keys, Devices, Release, Drawer, Buttons, Screen, Number, Total, Tax
Nouns (General Knowledge) 0-9 keys, Money, Subtotal Key, Tax Key, Total Key
Eliminating Irrelevant/Redundant Nouns We now analyze the identified nouns and try to establish whether they would be stand-alone classes in our domain or not. The outcome of this analysis is shown below.
- Register
- Display
- Wire → Irrelevant
- Plug → Irrelevant
- Keypad
- Keys
- Devices → Vague
- Release → Irrelevant
- Drawer
- Buttons → Redundant
- Screen → Redundant
- Number → Attribute
- Total → Attribute
- Tax → Attribute
- 0-9 Key
- Value → Attribute
- Money
- Subtotal Key
- Tax Key
- Total Key
We will continue with the technique to identify all the constituent components of the model and derive our object-oriented design.
🔑 Definition — Textual Analysis: A technique to identify objects and their relationships by mapping parts of speech in a specification to model components. 📌 Example: In the cash register problem, the noun "Wire" was identified as irrelevant, "Buttons" as redundant, and "Number" as an attribute, not a class.
⭐ Key Takeaways
Object-Oriented Design transforms an analysis model into a design model structured around four layers: subsystem, class and object, message, and responsibility. Object-Oriented Analysis focuses on defining all classes, their relationships, and their behavior through static and dynamic modeling. Abbot’s Textual Analysis is a practical technique for initially identifying model components by mapping parts of speech (nouns, verbs, adjectives) to objects, operations, and attributes. A critical step after identification is to eliminate irrelevant, redundant, or vague nouns and to correctly classify others as attributes rather than classes. The cash register example demonstrates how to apply Textual Analysis to a real problem statement to derive a clean set of classes for design.
🧠 Quick Revision Questions
- What are the four layers of the Object-Oriented Design pyramid?
- What is the primary intent of Object-Oriented Analysis (OOA)?
- In Abbot’s Textual Analysis, what model component does an "improper noun" (e.g., "student") map to?
- According to the lecture, why was the noun "Buttons" eliminated from the cash register example?
- What is the purpose of the "Eliminating Irrelevant/Redundant Nouns" step in Textual Analysis?
📘 Lecture 15 — The Notation
📖 Overview: This lecture introduces the various notations used for documenting object-oriented design, with a focus on the Unified Modeling Language (UML). It explains why notation is important in software engineering and presents UML as the standard choice for modern design documentation.
🗂️ Topics Covered
The lecture covers the three most popular notations for object-oriented design documentation: Rumbaugh, Booch, and Coad notation, with detailed emphasis on UML (Unified Modeling Language). The key features of UML notation are presented through a diagram, highlighting its comprehensiveness and detail for design documentation.
📝 Lecture Summary
The Notation
Many different notations are used for documenting object-oriented design. The most popular of these include Rumbaugh, Booch, and Coad notation, and UML (Unified Modeling Language). UML will be used to document the design in this course.
🔑 Definition — UML (Unified Modeling Language): A comprehensive and detailed notation standard used for documenting object-oriented software designs.
💡 Why this matters: Choosing a standard notation like UML ensures that design documents are universally understood by software engineers, reducing miscommunication and enabling better collaboration across teams.
📌 Example: The lecture refers to a diagram (not provided in text) that presents the key features of UML notation, showing its comprehensive nature for documenting object-oriented designs.
⭐ Key Takeaways
UML is the most popular and comprehensive notation for documenting object-oriented designs, and it will be the standard used throughout this course. While Rumbaugh, Booch, and Coad notations are also widely recognized, UML serves as the unified standard that incorporates elements from these earlier notations. Understanding UML notation is essential for effectively communicating software design decisions. The notation's key features are extensive and detailed, making it suitable for complex system documentation. Students must become familiar with UML's fundamental components to succeed in object-oriented design documentation.
🧠 Quick Revision Questions
- What are the four most popular notations mentioned for documenting object-oriented design?
- Which notation will be used in this course for documenting design?
- What does UML stand for?
- Why is notation important in object-oriented design documentation?
- How does UML compare in comprehensiveness to other notations like Rumbaugh, Booch, and Coad?
📘 Lecture 16 — Derivation of the Object Model – The Coad Methodology
📖 Overview: This lecture explains Peter Coad's systematic methodology for deriving object models in software engineering. It divides the process into five key activities, each with specific steps, enabling analysts to identify and categorize objects effectively. Understanding this methodology is crucial for building accurate and maintainable object-oriented system models.
🗂️ Topics Covered
The lecture covers the Coad Methodology for deriving an object model, focusing on five activities for selecting objects: selecting actors, participants, places, transactions, container objects, and tangible things. It also provides important considerations for simplifying the object model, such as ensuring each object has a clear responsibility, avoiding controller objects, and using meaningful domain-specific names.
📝 Lecture Summary
Select Objects – who am I?
This activity divides objects into different categories to make it easier to find them and establish their attributes, services, and collaborations. It consists of 6 steps.
Select Actors Actors are people and organizations that take part in the system under consideration. Examples include person, organization (agency, company, corporation, foundation). It is important to note that we are talking about actors and not their "roles". For example, a customer is a role that a person plays, so if we have a customer in our problem domain, we will also add a person as an actor in the model.
🔑 Definition — Actor: A person or organization that takes part in the system under consideration. 📌 Example: If a system has a "customer," we must also model "person" as an actor, because customer is a role that person plays.
Select Participants A participant is a role that each actor plays in the system under consideration. Examples include agent, applicant, buyer, cashier, clerk, customer, dealer, distributor, donor, employee, investor, member, officer, owner, policy holder, recipient, student, supervisor, supplier, teacher, worker. The same person may play different roles at different times in the system. If we model this behavior using Generalization-Specialization instead of Actor-Participant, we may end up with multiple inheritance.
🔑 Definition — Participant: A role that an actor plays in the system under consideration. 💡 Why this matters: Keeping actors and participants separate avoids complex multiple inheritance issues when a single person can play multiple roles.
Select Places Places are where things come to rest or places that contain other objects. Examples include airport, assembly-line, bank, city, clinic, country, depot, garage, hanger, hospital, plant, region, sales outlet, service center, shelf, station, store, warehouse, zone.
🔑 Definition — Place: An object that represents a location where things come to rest or that contains other objects.
Select Transactions Transactions are the "events" that must be remembered through time. These are entries that must be maintained in a historical record or log which may be used to answer questions or perform assessments. Transactions usually come from a window (GUI), an object that monitors for a significant event and logs that information, or another system that interacts with the system and logs some information. Examples include agreement, assignment, authorization, contract, delivery, deposit, incident, inquiry, order, payment, problem report, purchase, refund, registration, rental, reservation, sale, shift, shipment, subscription, withdrawal. Nearly all transactions consist of a number of transaction line items.
🔑 Definition — Transaction: An event that must be remembered through time, maintained in a historical record or log.
Select Container Objects Containers are objects that hold other objects. The difference between a container and a place is that a place is a place in the literal sense, while a container is any object that can hold other objects (e.g., bin, box, cabinet, folder, locker, safe, shelf). Therefore, a place is also a container, but every container need not be a place.
🔑 Definition — Container: An object that holds other objects (broader category than "place"). 📌 Example: A "shelf" is both a container and a place; a "folder" is a container but not a place.
Select Tangible Things Take a "walk" through the system and select "tangible" things around you used in the problem domain. These may be characterized as all the remaining (not yet selected) "nouns" that make up the problem domain. Examples include account, book, calendar, cash box, cash drawer, item, plan, procedure, product, schedule, skill, tool, etc.
Considerations for Selecting Objects
While selecting objects, the following considerations should be kept in mind for a simpler (and better) object model:
- Every object that you put in your object model should have some responsibility or role to play in the problem domain. You need to know each object, its attributes, and services. If there is no way to know about the object, remove it from the object model.
- Avoid having controller objects because controllers usually end up with functionality that's better done by other objects themselves, making the message passing more complicated, and resulting in higher coupling. Use delegation instead. The difference is that a controller wants to do everything by himself (doesn't trust anyone), while a good manager delegates responsibility (and takes credit).
- In large systems, several objects are likely to have similar or even identical responsibilities. Look for such objects and seek a common name to simplify the object model.
- Use meaningful class names, names that describe objects in that class. Try to use names from the domain vocabulary to avoid confusion.
🔑 Definition — Delegation: Assigning responsibility to other objects to perform tasks, rather than a controller doing everything itself. 💡 Why this matters: Delegation reduces coupling and simplifies message passing, whereas controllers create complex, tightly coupled systems.
⭐ Key Takeaways
The Coad Methodology provides a structured, step-by-step approach to identifying objects in an object model by categorizing them into actors, participants, places, transactions, containers, and tangible things. A key distinction is between actors (people/organizations) and participants (roles they play), which helps avoid multiple inheritance problems. Every object in the model must have a clear responsibility; objects without one should be removed. Avoid controller objects and instead use delegation to reduce coupling and simplify system design. Always use meaningful, domain-specific names for classes to ensure clarity and maintainability.
🧠 Quick Revision Questions
- What are the five main activities in Peter Coad's methodology for deriving an object model?
- What is the difference between an "actor" and a "participant"? Why is this distinction important?
- How do "places" and "containers" differ according to the Coad methodology?
- Why should controller objects be avoided in object models, and what should be used instead?
- What rule should you follow if you cannot determine an object's responsibility, attributes, or services?
📘 Lecture 17 — Identify Structures and Establishing Responsibilities
📖 Overview: This lecture focuses on two critical activities in object-oriented analysis: identifying structures (generalization-specialization and whole-part) and establishing object responsibilities (attributes, collaborations, and services). These steps transform a raw list of candidate objects into a well-organized, semantically rich domain model that captures both what objects know and what they do.
🗂️ Topics Covered
This lecture covers the identification of Gen-Spec and Whole-Part structures, then moves into establishing object responsibilities through three steps: defining attributes (what I know), showing collaborations (who I know), and defining services (what I do). For each step, specific guidelines and criteria are provided along with type-specific considerations for actors, participants, places, transactions, line items, and items.
📝 Lecture Summary
Identify Structures
A structure is a manner of organization which expresses a semantically strong organization within the problem domain. There are two types of structures: Generalization-Specialization (Gen-Spec) and Whole-Part. This activity identifies these structures in two steps:
🔑 Definition — Structure: A manner of organization expressing a semantically strong organization within the problem domain.
Step 1: Identify Gen-Spec Structures (Hierarchy) Consider each class you have identified as a specialization and then look for its generalization, and vice versa.
Step 2: Identify Whole-Part Structures (Aggregations) For each object you have identified, consider it as a whole and then try to find out its parts — objects that make up this object.
Define Attributes - What I Know?
After identifying objects, the first thing to consider is their attributes, i.e., what it knows. For each object, include the attributes that come to mind when you first think about the object. The criteria for inclusion: an attribute should be included if the system needs to know its value and it cannot get it any other way. Do not add an attribute for an association or aggregation. Examples of attributes include: number, name, address, date, time, operational state, phone, status, threshold, type.
💡 Why this matters: Proper attribute selection is critical because it directly impacts data integrity and system efficiency.
Type-specific attribute considerations:
- For actors: name, address, phone
- For participants: number, date and time, password, authorization level
- For place/location: number, name, address (perhaps latitude, longitude, altitude)
- For transaction: number, date, time, status
- For line item: quantity, status
- For item: name, description, dimension, size, UPC, weight
Issues to be aware of while defining attributes:
- An attribute that varies over time (e.g., price of an item) should be replaced by an additional class with an effective date and value
- An attribute that may have a number of values should be replaced by a new class and an object connection
- Replace “yes/no” type attributes with “status” type attributes for flexibility
- If there are classes with common attributes and generalization-specialization makes good sense, then add a generalization class and factor out the commonality
Show Collaborations (associations and aggregations) - Who I Know?
The second step in establishing each object’s responsibility is to identify and show how this object collaborates with other objects, i.e., who it knows. These collaborations can be identified with the following 8 steps:
- For an actor, include an object connect to its participants (association)
- For a participant, include an object connection to its actor (already established) and its transactions (association)
- For a location, include object connections to objects that it can hold (association), to its part objects (aggregation), and to the transactions taking place at that location (association)
- For transactions, include object connections to its participants (already established), its line items (aggregation), and its immediate subsequent transaction (aggregation)
- For a transaction line item, include object connections to its transaction (already established), its item (association), a companion “item description” object (association), and a subsequent line item (association)
- For an item, include object connections to transaction line item (already established), a companion “item description” object (association)
- For a composite object, include object connections to its “part” object (aggregation)
- For all objects (including all of the above) select connecting objects to which the object sends a message (within one or more scenarios) to get some information or to answer a query about objects directly related to it (association)
Define Services - What I Do?
The third and last step in establishing each object’s responsibility is to define what services does each object in the problem domain provide, i.e., what it does. Putting the right service with the right object is very important since any mistake in judgment will increase coupling and reduce cohesion. The verbs in your problem domain usually indicate some of the services required of the associated object.
🔑 Key Principle: Keep data and action together for lower coupling and better cohesion. Software objects do things that the system is responsible to do with regard to that object. By putting the services with the attributes they work on results in lower coupling, stronger cohesion, and increased likelihood of reuse.
📐 The basic services done by all (such as get, set, create, initialize) are not shown in the object model.
While establishing services for an object, these fundamental questions should be asked:
- Why does the system need this object anyway?
- What useful questions can it answer?
- What useful action can it perform?
- What can this object do, based upon what it knows?
- What can this object do, based upon whom it knows?
- What calculations can it do?
- What ongoing monitoring could it do?
- What calculations across a collection could it make (letting each worker do its part)?
- What selections across a collection could it make (letting each worker do its part)?
Type-specific service considerations:
- For an actor consider: calculate for me, rate me, is <value>, rank participants, calculate over participants
- For a participant consider: calculate for me, rate me, is <value>, rank transactions, calculate over transactions
- For a place consider: calculate for me, rate me, is <value>, rank transactions, calculate over contents, calculate over container line items
- For a Transaction consider: calculate for me, rate me, is <value>, how many, how much, rank transaction line items, rank subsequent transactions, calculate over transaction line items, calculate over subsequent transactions
- For a line item consider: calculate for me, rate me
- For an item consider: calculate for me, rate me, is <value>, how many, how much, rank, calculate over specific items
⭐ Key Takeaways
The lecture establishes a systematic three-step method for assigning responsibilities to objects: define attributes (what I know), show collaborations (who I know), and define services (what I do). For attributes, the critical rule is to include an attribute only if the system needs its value and cannot derive it otherwise, and to replace time-varying or multi-valued attributes with separate classes. For collaborations, eight specific step-by-step guidelines cover all standard object types from actors to composite objects. For services, the fundamental principle is to keep data and action together to achieve lower coupling and higher cohesion, with the basic CRUD services (get, set, create, initialize) being implied and not shown in the model. The type-specific checklists for all three responsibility areas provide concrete guidance that helps ensure no important attributes, collaborations, or services are overlooked.
🧠 Quick Revision Questions
- What are the two types of structures identified during object-oriented analysis, and what is the focus of each type?
- What is the inclusion criterion for an attribute, and what should you do with attributes that vary over time or can have multiple values?
- What is the basic principle for assigning services to objects, and which services are typically not shown in the object model?
- List the eight steps for identifying collaborations (associations and aggregations) for different object types.
- What are the nine fundamental questions that should be asked when establishing services for an object?
📘 Lecture 20 — Interaction Diagrams – Depicting the Dynamic Behaviour of the System & Evaluating the Quality of an Object-Oriented Design
📖 Overview: This lecture explains how to model the dynamic behavior of an object-oriented system using interaction diagrams, specifically sequence and collaboration diagrams. It also covers how to evaluate the quality of an object-oriented design by analyzing encapsulation, delegation, coupling, and cohesion to create maintainable systems.
🗂️ Topics Covered
The lecture covers interaction diagrams for modeling dynamic behavior, including sequence diagrams with their notation, life lines, activation boxes, and message types (synchronous, asynchronous, create, destroy). It then covers collaboration diagrams as an alternative organizational view, comparing them with sequence diagrams. Finally, it addresses evaluating object-oriented design quality through centralized vs. distributed control, encapsulation, delegation, and reducing coupling.
📝 Lecture Summary
Interaction Diagrams – depicting the dynamic behaviour of the system
A series of diagrams can describe the dynamic behavior of an object-oriented system through messages exchanged among objects within a context to accomplish a purpose. This models how a use case is realized via a sequence of messages between objects.
The purpose of interaction diagrams is to:
- Model interactions between objects
- Assist in understanding how a system (a use case) actually works
- Verify that a use case description can be supported by existing classes
- Identify responsibilities/operations and assign them to classes
UML provides two mechanisms to document dynamic behavior: sequence diagrams (time-based view) and collaboration diagrams (organization-based view).
The Sequence Diagram
Sequence diagrams illustrate how objects interact, emphasizing time ordering of messages arranged in time sequence. They can model simple sequential flow, branching, iteration, recursion, and concurrency. The focus is on objects (and classes) and message exchanges among them. Objects are organized horizontally, and events on a vertical timeline.
The Notation
The notation uses:
- Boxes denote objects (or classes)
- Solid lines depict messages sent from one object to another
- Dotted lines are life lines representing the object’s life during interaction
- Activation boxes on life lines show how long a particular message will be active
- Conditions can be shown in brackets before a message
🔑 Definition — Life line: The dotted vertical line representing an object's existence during an interaction.
📐 Syntax for naming objects: [instanceName][:className] — Name classes consistently with your class diagram. Include instance names when objects are referred to in messages or when several objects of the same type exist.
📌 Example: In the library sequence diagram, member:LibraryMember sends mayBorrow() to itself, then if ok is true, sends borrow(book) to book:Book.
A message is represented by an arrow between life lines of two objects. For a message to be sent, an association must exist between those objects — either the receiver is in the global scope, local scope (method argument), or they are the same object. Self calls are also allowed.
Message Types
Sequence diagrams depict different types of messages:
Synchronous Messages — “Call events” denoted by a full arrow. They represent nested flow of control (operation call). The caller waits for the called routine to complete before moving forward. Return values can be indicated optionally using a dashed arrow.
📌 Example: Object :A sends doYouUnderstand() to :B — :A is blocked until :B returns (optional) yes.
Guidelines for synchronous messages:
- Don’t model a return value when it is obvious (e.g.,
getTotal()) - Model a return value only when you need to refer to it elsewhere (e.g., as a parameter)
- Prefer modeling return values as part of a method invocation (e.g.,
ok = isValid())
Asynchronous Messages — “Signals” denoted by a half arrow. They do not block the caller. The caller does not wait for completion. This occurs in multi-threaded or multi-processing applications.
Asynchronous messages typically perform:
- Create a new thread
- Create a new object
- Communicate with a thread already running
Object Creation and Destruction — An object may create another via a <<create>> message and destroy via <<destroy>> message. An object may also destroy itself. Avoid modeling object destruction unless memory management is critical. The life line is affected accordingly.
📌 Example: Object :A sends <<destroy>> to :B, ending :B's life line. Similarly, :A may receive <<destroy>> to terminate itself.
Sequence diagrams and logical complexity
The golden principle: keep it small and simple. Diagrams are meant to make things clear. For simple conditional logic, add it to the diagram. For complex logic, draw separate diagrams like flowcharts.
Collaboration diagrams
Collaboration diagrams depict dynamic behavior with respect to organizational units (boundaries). Boundaries shape communication between system and outside world (e.g., user interface or other systems). The sequence of messages is determined by numbering (1, 2, 3, 4...), showing which operation calls which.
Collaboration diagrams have two components: objects and messages. They can show synchronous, asynchronous, create, and destroy messages using the same notation as sequence diagrams. Messages are numbered and can have loops.
📌 Example: In the course registration system: 1: set course info from Registrar to course form, 2: process, 3: add course to theManager, 4: <<create>> aCourse.
Comparing sequence & collaboration diagrams
- Sequence diagrams are best for seeing the flow of time
- Collaboration diagrams best represent static object connections
- Sequence of messages is more difficult to understand in collaboration diagrams
- Object organization with control flow is best seen through collaboration diagrams
- Complex control is difficult to express in either, but collaboration diagrams can become very complex very quickly
Evaluating the Quality of an Object-Oriented Design
We can analyze encapsulation and delegation to judge whether control is centralized or distributed, hence judging coupling and cohesion. OO design yields more cohesive and loosely coupled systems.
Centralized vs. Distributed Control — Illustrated with a heat regulatory system:
- Poor design (distributed): A
Heat Flow Regulatorcommunicates with three separate objects (Desired Temp,Actual Temp,Occupancy) — high coupling - Better design (encapsulated): The three objects are encapsulated into one
Roomobject — reduced coupling, but control still centralized in the regulator - Best design (delegated): Responsibility is delegated to the
Roomobject with a single messagedoYouNeedHeat()— reduced coupling even further, more cohesive
💡 Why this matters: Encapsulating related data and behavior into one object and delegating responsibility reduces the number and types of messages, making classes easier to understand and modify.
Reducing coupling by minimizing the number of messages in a class's protocol (public interface):
- Example: Replace
SetMinimumValue(int aValue)andSetMaximimumValue(int aValue)withSetLimits(int minValue, int maxValue) - This reduces protocol complexity
- Caution: Use heuristics judiciously so the function’s scope does not go beyond providing one single operation
⭐ Key Takeaways
The most critical concepts from this lecture are: (1) Sequence diagrams show time-ordered messages between objects with life lines and activation boxes, while collaboration diagrams show object organization with numbered messages. (2) Message types include synchronous (blocking caller), asynchronous (non-blocking), create (<<create>>), and destroy (<<destroy>>). (3) To evaluate design quality, examine control distribution: centralized control with many messages indicates poor design; encapsulated and delegated control reduces coupling and increases cohesion. (4) Reducing the number of messages in a class's public protocol makes it easier to understand and modify, but avoid over-consolidating unrelated operations. (5) Collaboration diagrams become complex quickly with complex control flow, while sequence diagrams are better for time-based understanding.
🧠 Quick Revision Questions
- What is the difference between a synchronous message and an asynchronous message in a sequence diagram?
- What does a life line represent, and how does an activation box relate to it?
- In the heat regulatory system example, why is delegating the
doYouNeedHeat()responsibility to the Room object better than having the Heat Flow Regulator query three separate objects? - When should you avoid modeling object destruction in a sequence diagram?
- What is the main advantage of collaboration diagrams over sequence diagrams, and what is their main disadvantage?
📘 Lecture 22 — Software and System Architecture
📖 Overview: This lecture introduces the concept of software architecture, tracing its historical roots to Dijkstra and Parnas, and defines it through multiple authoritative perspectives. It explains why architecture is critical for communication, early design decisions, and reuse, and outlines architectural attributes and the design process. Understanding architecture is essential because it establishes the structural foundation that dictates a system's quality, development, and maintenance.
🗂️ Topics Covered
The lecture begins with an introduction to architectural design and its historical origins with Dijkstra's layered structures and Parnas's information-hiding modules and program families. It then covers multiple formal definitions of software architecture from UML, Bass/Clements/Kazman, Garlan and Perry, IEEE, and Shaw and Garlan. The importance of architecture is explained through three key reasons: mutual communication among stakeholders, early design decisions that constrain implementation and work breakdown, and reusable abstraction for product lines. Finally, the lecture addresses architectural attributes (performance, security, safety, availability, maintainability) and the architectural design process (system structuring, control modeling, modular decomposition).
📝 Lecture Summary
Introduction
The lecture opens by analogizing software architecture to building architecture, where different stakeholders (architect, contractor, electrician, plumber) have different but related views of the same structure. Architectural design establishes the overall structure of a software system by identifying sub-systems and the framework for their control and communication. The study of software architecture began in 1968 when Edsger Dijkstra introduced the layered structure, where programs are grouped into layers and can only communicate with programs in adjoining layers, yielding conceptual integrity and gains in development and maintenance ease. David Parnas advanced this with contributions on information-hiding modules, software structures, and program families—a set of programs considered as a group because it is profitable or useful to do so. Parnas argued that early design decisions should be those most likely to remain constant across members of a program family (such as adopting a particular architecture), while late design decisions should be trivially changeable (such as compile-time or load-time constants). All work in software architecture evolves toward a paradigm based on principles of architecture because structure is important and getting it right carries benefits.
8.2 What is Software Architecture?
There is no single universally accepted definition of software architecture, but at its essence is a focus on reasoning about structural issues of a system. A system is defined by UML 1.3 as a collection of connected units organized to accomplish a specific purpose, and by IEEE Std. 610.12-1990 as a collection of components organized to accomplish a specific function or set of functions.
🔑 Definition — System (UML 1.3): a collection of connected units that are organized to accomplish a specific purpose.
🔑 Definition — System (IEEE Std. 610.12-1990): a collection of components organized to accomplish a specific function or set of functions.
Software Architecture Definitions:
🔑 Definition — Architecture (UML 1.3): the organizational structure of a system, which can be recursively decomposed into parts that interact through interfaces, relationships that connect parts, and constraints for assembling parts. Parts that interact through interfaces include classes, components, and subsystems.
🔑 Definition — Architecture (Bass, Clements, Kazman): the structure or structures of the system, which comprise software components, the externally visible properties of those components, and the relationships among them. "Externally visible" properties refer to assumptions other components can make about a component, such as its provided services, performance characteristics, fault handling, and shared resource usage. The architecture must abstract away some information yet provide enough to be a basis for analysis, decision making, and risk reduction.
🔑 Definition — Architecture (Garlan and Perry): the structure of the components of a program/system, their interrelationships, and principles and guidelines governing their design and evolution over time.
🔑 Definition — Architectural design (IEEE Glossary): The process of defining a collection of hardware and software components and their interfaces to establish the framework for the development of a computer system.
🔑 Definition — Architecture (Shaw and Garlan): the system defined in terms of computational components and interactions among those components. Components include clients, servers, databases, filters, and layers. Interactions include procedure call, shared variable access, client-server protocols, database accessing protocols, asynchronous event multicast, and piped streams.
💡 Why this matters: Although these definitions differ in wording, they do not conflict; all emphasize structural issues and ways to describe them. Architectural design is an early stage of system design that represents the link between specification and design, provides an abstract view of the solution, identifies critical issues, documents design choices under constraints, and primarily defines non-functional requirements and the environment.
8.3 Why is architecture important?
Barry Boehm states that if a project has not achieved a system architecture, including its rationale, it should not proceed to full-scale system development. There are three fundamental reasons architecture is important:
🔑 1. Mutual communication: Software architecture represents a common high-level abstraction that most system stakeholders (customer, user, project manager, coder, tester) can use as a basis for mutual understanding, consensus, and communication. It provides a common language in which different concerns can be expressed, negotiated, and resolved at an intellectually manageable level, even for large, complex systems.
🔑 2. Early design decisions: Software architecture embodies the earliest set of design decisions about a system, and these early bindings carry weight far out of proportion to their individual gravity. An implementation exhibits an architecture if it conforms to the structural design decisions—divided into prescribed components, interacting in prescribed fashion, with each component fulfilling its responsibility. Resource allocation decisions also constrain implementation, enabling separation of concerns. The architecture prescribes not only the system structure but also engraves that structure on the work breakdown structure—the division of labor in a large system, with different groups assigned different portions. The work breakdown structure dictates units of planning, scheduling, budget, inter-team communications channels, configuration control, integration, test plans, and maintenance activities.
💡 Why this matters: A side effect of establishing the work breakdown structure is to effectively freeze the software architecture, making it almost impossible to modify for managerial and business reasons. This is why extensive analysis must be carried out before freezing the architecture. Fortunately, it is possible to make quality predictions about a system based solely on an evaluation of its architecture.
🔑 3. Reusable abstraction of a system: Software architecture embodies a relatively small, intellectually graspable model for how the system is structured and how its components work together. This model is transferable across systems and can promote large-scale reuse. In product line development, the architecture defines what is fixed for all members of the family and what is variable. System architects choose an architecture that serves all envisioned members by making design decisions that apply across the family early and decisions that apply only to individual members late. A family-wide design solution may not be optimal for all derived systems, but the quality gained and labor savings from architectural-level reuse may compensate for non-optimality.
8.4 Architectural Attributes
Software architecture must address non-functional as well as functional requirements. The following are architectural design guidelines for addressing these challenges:
- Performance: Enhanced by localising operations to minimise sub-system communication—use self-contained modules to minimize inter-module communication.
- Security: Improved by using a layered architecture with critical assets placed in inner layers.
- Safety: Safety-critical components should be isolated.
- Availability: Ensured by building redundancy in the system with redundant components in the architecture.
- Maintainability: Directly related to simplicity; increased by using fine-grain, self-contained components.
8.5 Architectural design process
The design of software architecture is a creative and iterative process involving several activities:
🔑 System structuring: Decomposing the system into interacting sub-systems. The system is decomposed into principal sub-systems, and communications between them are identified. The architectural design is normally expressed as a block diagram presenting an overview of the system structure. A sub-system is a system in its own right whose operation is independent of services provided by other sub-systems. A module is a system component that provides services to other components but would not normally be considered a separate system.
🔑 Control modelling: Establishes a model of the control relationships between the different parts of the system.
🔑 Modular decomposition: The identified sub-systems are decomposed into modules.
⭐ Key Takeaways
The most critical things to remember are: (1) Software architecture is about the structural organization of a system—its components, their externally visible properties, and their relationships—and it defines the framework for sub-system control and communication. (2) Architecture is important for three key reasons: it enables mutual communication among stakeholders, it embodies early design decisions that constrain the entire development and work breakdown structure, and it provides a reusable abstraction for product lines. (3) Non-functional attributes (performance, security, safety, availability, maintainability) must be addressed architecturally through specific design guidelines like localizing operations, layering for security, isolating safety-critical components, building redundancy, and using fine-grain self-contained modules. (4) The architectural design process is iterative and includes system structuring (decomposing into sub-systems), control modeling (establishing control relationships), and modular decomposition. (5) Once the architecture's module structure is agreed upon and used as the work breakdown structure, it becomes nearly impossible to modify for managerial and business reasons, so extensive analysis must precede freezing the architecture.
🧠 Quick Revision Questions
- What did Dijkstra contribute to the study of software architecture, and what was his key concept?
- According to Bass, Clements, and Kazman, what are "externally visible properties" of a component in an architectural definition?
- List and explain the three fundamental reasons why software architecture is important.
- For each of the following architectural attributes, give one design guideline: performance, security, safety, availability, and maintainability.
- Describe the three main activities in the architectural design process: system structuring, control modeling, and modular decomposition.