← back

Undergraduate Course Overview

This undergraduate Software Engineering course provides a research-informed, practice-driven foundation for educating the next generation of software engineers capable of building secure, reliable, and maintainable software systems. The course integrates core software engineering principles, modern development practices, and emerging AI-assisted tooling, aligning with national workforce needs and NSF priorities in trustworthy computing, software infrastructure, and cyberinfrastructure education.

Rather than treating software engineering as a collection of isolated techniques, the course presents it as a disciplined, lifecycle-oriented engineering activity, emphasizing how early design decisions influence maintainability, security, scalability, and long-term cost. Students engage with both classical engineering models and modern agile workflows, preparing them to reason about real-world trade-offs in complex software systems.


Lifecycle-Centered Engineering Foundations

Students are introduced to the full software engineering lifecycle, including requirements engineering, system modeling, architectural design, implementation, validation and testing, and maintenance and evolution. Through lectures and hands-on exercises, students examine why software failures and escalating maintenance costs frequently arise from unmanaged complexity, weak requirements, and poor architectural decisions.

Quantitative concepts such as software size, cyclomatic complexity, and change propagation are used to ground abstract ideas in measurable engineering outcomes, reinforcing an evidence-based approach to software quality. This lifecycle framing supports the development of robust, sustainable software systems.


Requirements Engineering and System Modeling

A central component of the course is requirements engineering, where students learn to translate stakeholder needs into clear, precise, and testable specifications. Emphasis is placed on distinguishing user requirements from system requirements, managing both functional and non-functional constraints (e.g., performance, security, reliability), and validating requirements throughout development.

Students develop proficiency in software system modeling using Unified Modeling Language (UML). They construct and analyze use case diagrams, sequence diagrams, class diagrams, state diagrams, and activity diagrams, learning how multiple system views interact to reduce ambiguity and support early validation. These modeling activities foster disciplined reasoning about system structure and behavior before implementation.


Architectural Design and Reusable Patterns

The course emphasizes architectural design as a critical bridge between requirements and detailed software design. Students study widely adopted architectural patterns, including Model–View–Controller (MVC), layered architectures, client–server systems, and pipe-and-filter designs, and analyze how architectural decisions shape scalability, performance, security, and maintainability.

Building on architectural principles, students engage deeply with software design patterns across structural, behavioral, and creational categories. Through code-driven examples, students learn how patterns such as Composite, Adapter, Bridge, Façade, Proxy, Command, Observer, Strategy, Visitor, and Builder provide reusable solutions to recurring design problems. These patterns are connected to modern development tasks such as program analysis, resource management, and tool construction, reinforcing principled software design.


Agile Development, Testing, and Quality Assurance

Modern agile software development practices form a core thread throughout the course. Students study Extreme Programming (XP) and Scrum, focusing on iterative development, continuous feedback, refactoring, and test-driven development (TDD). Refactoring is treated as a disciplined activity for improving code structure without changing external behavior, supporting long-term maintainability.

Automated testing is emphasized as a first-class engineering activity. Students gain hands-on experience with unit testing, server-side testing, and end-to-end web application testing using tools such as Pytest and Selenium. These practices reinforce the importance of software correctness, regression prevention, and continuous integration in professional software development.


Cloud Platforms and Professional Tooling

The course integrates cloud-based development environments using platforms such as Amazon Web Services (AWS) and Google Cloud Platform. Students deploy and test web applications on remote Linux servers, gaining practical experience with virtual machines, network configuration, and secure access control.

Professional development workflows are emphasized through the use of Visual Studio Code Remote–SSH, secure authentication, and remote debugging. These experiences expose students to industry-standard tooling, strengthen their understanding of distributed systems, and prepare them for collaborative development in modern cloud-based environments.


Team-Based Term Project and Collaborative Learning

A central component of the undergraduate Software Engineering course is a team-based term project that provides students with sustained, hands-on experience applying software engineering principles in a realistic development setting. Students work in small, diverse teams to design, implement, test, and deploy a non-trivial software system over multiple iterations, mirroring professional software development environments.

The term project emphasizes collaborative engineering practices, including requirements negotiation, task decomposition, role assignment, and coordination across technical and non-technical responsibilities. Teams are required to manage shared codebases using version control systems, conduct code reviews, and integrate individual contributions through disciplined branching and merging workflows. These activities reinforce the importance of communication, accountability, and shared ownership in large-scale software projects.

Throughout the semester, project milestones are aligned with lecture topics, allowing students to incrementally apply concepts such as requirements engineering, system modeling, architectural design, design patterns, agile planning, and automated testing. By revisiting and refining earlier design decisions, students gain first-hand experience with software evolution, refactoring, and technical debt management, highlighting the long-term consequences of early engineering choices.

The team-based structure also supports the development of professional and interpersonal skills, including technical communication, conflict resolution, and peer feedback. Students practice presenting design rationales, documenting decisions, and justifying trade-offs, preparing them for participation in multidisciplinary and distributed development teams. This collaborative project experience directly aligns with NSF priorities in workforce preparation, collaborative problem solving, and experiential learning.


Educational and Broader Impacts

From an educational and workforce development perspective, this course prepares students for high-demand computing careers by combining engineering rigor with use-inspired, hands-on practice. Students gain practical experience designing, implementing, testing, and evolving software systems using modern tools and workflows that reflect professional software development environments. The curriculum lowers barriers to participation through tool-supported learning and emphasizes learning by doing, enabling students to build confidence through sustained, real-world problem solving.

The course is designed to be extensible and adaptable, supporting integration with undergraduate research, capstone projects, and project-based learning initiatives across computing disciplines. By engaging students in team-based development, iterative refinement, and evidence-based decision making, the course prepares graduates to contribute effectively to collaborative software projects, adapt to evolving technologies, and participate in interdisciplinary teams. Overall, the course advances workforce readiness by cultivating practical skills, professional habits, and a strong foundation in building robust, maintainable, and scalable software systems.