Home - SYSC3020-Winter2016/SYSC3020LectureNotes GitHub Wiki
Welcome to the SYSC3020 Lecture Notes! This page lists the course overview and will point you to the various sub-pages.
What is Software Engineering?
- Definitions
- Purpose: Improve Software Quality, lower costs
- Activities Involved
History
- A brief look at the history of computing and its difficulties.
Why do we need it?
- Pressure on quality and costs.
- High Complexity of modern systems
- Large development teams need to be coordinated
- Software Engineering Failures
How does it address the problem?
[Dutoit] A requirement is a feature that the system must have or a constraint that it must satisfy to be accepted by the customer.
We distinguish functional and non-functional requirements.
The requirement specifications define what needs to be implemented, and serve as a (formal or informal) contract between the customer and the development team. Many SE Failures come from poorly defined requirements (imprecise, incomplete, or plain wrong).
The first phase is the elicitation process with the customer (and other stakeholders), and the second phase is the analysis phase, where these requirements are formalized in a technical document.
In practice, elicitation and analysis are done jointly. However, the elicitation model (called the system specification) is for the customer whereas the analysis model is intended for the developer.
One functional specification of a software system is usually described as a Use Case. A combination of use cases describe the whole of the software system's functional specification. The use cases and their relationships are summarized in a Use Case Diagram, and use case descriptions follow set guidelines.
Object-oriented analysis aims to produce an analysis model of the system, which is correct, complete, consistent, and verifiable. This model refines and details the use case model, and will also go into the requirements analysis document.
The analysis model consists of the functional model, the static (object) model, and the dynamic model.
Formalizing the requirements into a model forces the developer (or analyst) to identify and resolve difficult issues early on.
- The Object Model is a model of the problem domain, describing the concepts of the domain and their relationships
- Relationships between concepts are described by associations, which include simple association, composition, generalization.
- The object model is represented in by a UML class diagram
- The main heuristics to identify the relevant classes and associations are based on text analysis (Abbott).
- Once objects have been specified, complex behavior (use cases or parts of use cases) can be specified using dynamic models, in particular finite state machines
- In UML, these translate as statechart diagrams.
- The interaction between objects can also be represented by UML sequence diagrams.
- The concepts in the object model can be divided between entity, boundary, and control objects
- This taxonomy provides a method to design the system from the object model. [Method by Ivar Jacobson].
- Objects of each type can be identified using heuristics based on the text of the requirements description.
Complex systems must be decomposed into subsystems:
- Reduce complexity by separating concerns
- The system architecture refers to this decomposition and the relationships between the subsystems.
- In a modular system, the subsystems should be decoupled (from each other) and highly cohesive (internally).
- Allow multiple teams to work concurrently
- Reuse existing components
Large systems are often distributed across multiple platforms /processors. The Process Architecture has a strong impact on system complexity and performance
- Persistent data outlives a single execution of a system
- Persistent data can be stored in flat files or in database management systems
- This choice is based on performance, the complexity of queries (data retrieval and update tasks), cost and administration capabilities
The main choices are:
- Flat files
- Relational databases (SQL)
- NoSQL databases: key-value stores, document databases, graph databases...
All users may not access all the functionality of a system. Access control must be Access Control Policies (not hard-coded) and secure, using cryptography to prevent unauthorized access.
The global control flow of the system may be:
- Procedure-driven control
- Event-driven control
- Threads
The boundary conditions are the system startup, shutdown, and exception handling. These require special consideration, in particular with respect to data storage.
One of the important decisions of the design stage is the Software Reuse.
A few important design patterns:
- Observer Design Pattern
- Adapter Design Pattern
- Strategy Design Pattern
- Factory Method Pattern
- Facade Design Pattern
- Singleton Design Pattern
- Composite Design Pattern
Validation is about making sure we're building the right program, i.e. that it complies with the requirements, both functional and non-functional.
Verification is about making sure we're building it well: verifying that our work products meet quality standards:
- UML diagrams must be correct and consistent
- The code must be well documented, and must not crash (e.g. null pointer exceptions, segmentation faults...)
- The tests must be high quality (see: Verifying Tests)
Does the program do what it is supposed to do? Can we prove it? Functional tests are validation: testing against specification. This is primarily done by Black-box Testing techniques.
[White-box testing] techniques are intended to optimize the code coverage of tests.
Static code analysis: verifying code without executing it.
Will the system work fast enough? under high workloads? How long will it last ? An important topic: Memory Leaks.
Can we trust this application? This is relevant for code acquired from third parties... you expect in-house built code to be ok. - apps on the apple store...
- No client
- Can't afford to go through the traditional processes
- Today: Web, Mobile