0% found this document useful (0 votes)
14 views80 pages

1.1 What's Software Engineering?: Difference Between UML & SE

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views80 pages

1.1 What's Software Engineering?: Difference Between UML & SE

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 80

1 Introduction

1.1 What’s Software Engineering?


Software Engineering is a branch in the field of Computer Science that revolves around designing, testing, coding, and maintaining high-quality
software while being able to understand the needs of the client.

1.2 What’s the Difference Between a Programmer and a Software Engineer?


People often confuse a programmer with a software engineer. While it is true that both write code for software, a software engineer is a step ahead
of the programmer. Not only does the engineer program, but they also possess non-technical skills that allow them to understand and guide
the client according to their needs, create the architecture of the software, and apply various techniques and methodologies for well-structured
software. In other words, a programmer ⊂ software engineer.

Software Enginner’s Skill

Problem-Solving
Deploying And

Conception
Maintaining
Design
Programming Softwares
And

UML

Collaborating And Non-technical Skills

Difference Between UML & SE


SE ̸⇔ UML

Many people tend to confuse UML, which is merely a tool used for visualizing client needs, software architectures, and other elements
in easy-to-understand diagrams, with software engineering, which involves the entire project creation process . UML is simply one of
many skills within the field of software engineering.

1
2 The Birth of Software Engineering
2.1 Development of Hardware/Software and Their Relationship
• 1940-1950: Vacuum Tubes: Vacuum tubes were electronic components that controlled the flow of electricity in a vacuum. Used in
radios, televisions, and early computers, they were large, expensive, and consumed a lot of power, but were essential for electronics at the
time.
• 1950-1960: Transistors: Transistors are semiconductor devices used to amplify or switch electronic signals. They replaced vacuum
tubes due to their smaller size, greater efficiency, and lower cost. Transistors were used in radios, early computers, and have since become
fundamental in all modern electronics.

• 1960-1970: Integrated Circuits: An integrated circuit (IC) is a small chip that contains a set of electronic circuits, including transistors,
resistors, and capacitors. ICs made electronics more compact, affordable, and powerful, revolutionizing industries during the 1960s. ICs
were found in computers, calculators, and a wide range of other electronic devices.
• 1970-Present: Microprocessors: A microprocessor is a single-chip CPU (Central Processing Unit) that performs the functions of a
computer’s central processor. Microprocessors became more affordable in the 1970s, paving the way for the rise of personal computers,
smartphones, and embedded systems in countless devices today.

Software
Hardware
P rice

T ime

As shown in the graph above, there is an inverse relationship between hardware and software prices. As hardware becomes more affordable
and advanced, software prices tend to increase, a phenomenon often referred to as the ”Software Crisis.” This was primarily caused by a lack
of development methodology and reflection on part of the developers. Software projects frequently went over budget, were late to release, and
were often filled with bugs.
To address this issue, developers needed to establish efficient methodologies and practices for building better software.

2
2.2 Qualities of Good Software
A well-designed software product must meet several key criteria to be considered high-quality. Here are some essential qualities:

• Maintainability: The ease with which software can be modified to correct faults, improve performance, or adapt to a changed environment.
Code should be well-documented, modular, and easy to update without causing regressions in other parts of the software.
• Affordability: High-quality software should provide value for money. The cost of development, licensing, maintenance, and support
should be reasonable and aligned with the customer’s budget and expectations. Affordability doesn’t mean the cheapest option, but one
that balances cost with features and reliability.
• Functionality: The software must meet the specific needs of its users and perform the tasks it was designed for effectively. It should
deliver all required features and capabilities, ensuring that it fulfills its purpose.
• Reliability: Software should function consistently and accurately over time, without crashing or producing incorrect results. It should
handle errors gracefully and work well under various conditions, including edge cases and unexpected inputs.

• Performance: Good software should operate efficiently, with fast response times and minimal use of system resources. Performance
includes aspects like load times, memory usage, and the ability to handle multiple tasks or large amounts of data simultaneously.
• Scalability: The software should be able to grow and accommodate increasing amounts of work or users without a significant drop in
performance. This is especially important for systems that expect long-term growth or fluctuating demand.

• Usability: The user interface should be intuitive, making it easy for users to learn and navigate. Well-designed software provides a
positive user experience, with thoughtful layouts, clear instructions, and accessible features for all users, including those with disabilities.
• Security: Security is critical in today’s environment. High-quality software should protect user data and prevent unauthorized access,
ensuring compliance with security standards. It should include features like encryption, authentication, and protection against common
vulnerabilities such as SQL injection or cross-site scripting.

• Portability: Software should work across different platforms and environments with minimal modifications. This is especially important
for applications intended to run on multiple operating systems, browsers, or devices. A portable software solution can save significant
development effort.
• Interoperability: High-quality software should be able to integrate and work seamlessly with other systems and tools. This includes
support for standard formats, APIs, and protocols that allow it to exchange data and collaborate with other software.
• Minimization of Bugs: A good software product should have a minimal number of defects. This involves rigorous testing during the
development process to catch and fix bugs early, as well as ongoing maintenance and updates to address issues as they arise.
• Extensibility: Software should be designed in a way that allows new features and functionality to be added in the future without
significant changes to the core architecture. Extensible software can adapt to changing user needs and technology advances.

• Compliance with Standards: High-quality software adheres to industry standards and regulations, ensuring that it meets legal,
technical, and ethical guidelines. This is particularly important in industries like healthcare, finance, and government, where compliance
is mandatory.

3
P rice Quality

This graph illustrates the positive correlation between software quality and price. As the quality of the software improves, its price tends to
increase exponentially.

4
3 Life Cycle Of Software
3.1 Whats’s Life Cycle Of Software?
As the name suggest it’s the life cycle of a software from start to finish , life cycle also known as model is a methodology that serves to help
developers in building their product , each life cycle has steps and a chronology to follow

3.2 Waterfall Life Cycle


The Waterfall Model is considered one of the first software development methodologies for large-scale projects. As the name suggests, it follows
a series of sequential steps, one after the other, similar to a waterfall. This model formed the basis of early software life cycles, solving many
issues but also introducing some new challenges. Over time, other life cycle models were developed and improved upon.

3.2.1 First Version


The first version of the WaterFall model includes 5 steps
• Definition & Needs Analysis: The first step involves interacting with the client to understand their requirements and guide them.
This step is crucial because any misunderstanding between the developers and the client could cause the entire project to fail, requiring a
restart. The output of this step is a document that contains all the necessary information, called the ”Requirements Document.”
• Design: In this step, developers create the software’s architecture, defining the modules and how they interact with each other. The
output of this step is the ”Design Document.”
• Coding: The implementation of the modules into a programming language takes place in this step.
• Testing: This step involves testing the software and fixing bugs.
• Deployment & Maintenance: The final step is delivering the software to the client and maintaining it by adding new features and
fixing undetected and future bugs.

Requirements Document
Definition & Needs Analysis

Design Document
Design

Software’s Modules
Coding

Software
Testing

Deployment & Maintenance

5
3.2.2 Improved Version
The Waterfall model was slightly improved by dividing some steps into two:
• Design:

– Architectural Design: Design how the software’s modules will interact with each other.
– Detailed Design: Design each module’s components in detail.
• Testing:
– Unit Testing: Test all the modules independently.
– Integration Testing: Test the interaction and communication between modules.

Requirements Document
Definition & Needs Analysis

Achitectural
Design
Design Document

Detailed
Design Software’s Modules
Coding

Unit
Testing
Software

Integration
Testing
Deployment & Maintenance

6
Note
Why Architectural Design before Detailed Design?

We first define the high-level structure of the modules and their interactions to provide an overall system architecture. This gives a
clear overview of the software before delving into the detailed characteristics of each module.

Why Unit Testing before Integration Testing?

It is important to test each module individually to ensure that they function correctly in isolation. This helps to simplify debugging,
as any issues can be pinpointed within a module, rather than confusion over whether the problem lies in the module itself or in the
interaction between modules.

3.2.3 Pros
• Helps organize the project by providing a clear structure and well-defined stages.
• Simple to understand and execute, especially for small to medium-sized projects.
• Easy to manage due to its linear progression, making it suitable for projects with stable requirements.

• Documentation is thorough, ensuring that each phase has a clear output.

3.2.4 Cons
• Lack of parallelism, as tasks cannot be done concurrently, leading to longer project timelines.
• High dependency between steps, meaning each phase must be completed fully before the next can begin.
• Inflexibility to handle changes during development, as going back to previous phases can be costly and time-consuming.

• Risk of significant rework if the needs analysis phase is not done properly, potentially requiring a restart from the beginning.
• Limited feedback during development, as testing and validation occur only at later stages.

3.3 V Life Cycle


The V Model is similar to the Waterfall Model, as both follow a sequential process with the same key steps. However, the V Model introduces
a key difference: it integrates preparation for the corresponding testing phases alongside each development step, forming a ”V” shape in the
process diagram. For example, after completing the Architectural Design, preparation for Integration Testing begins. Similarly, after the
Detailed Design, preparation for Unit Testing takes place. This parallel preparation ensures better alignment between development phases
and their corresponding testing phases, saving time and helping to catch potential issues earlier.

7
Prepation
Definition & Needs Analysis Acceptation Test

Prepation
Architectural Design Integration Test

Prepation
Detailed Design Unit Test

Coding

Note
It’s important to note that while there is parallelism in the preparation for testing, the development steps themselves are still executed
sequentially, with no overlap.

3.3.1 Pros
• Improves time efficiency by preparing testing phases in parallel with development phases, allowing for faster transitions between steps.
• Allows early detection of potential issues, as test preparation begins immediately after design, enabling a quicker response to design flaws
or misunderstandings.

3.3.2 Cons
• Lacks parallelism in the execution of development steps, as each phase must still be completed sequentially.
• Carries the risk of significant rework if the needs analysis phase is not thoroughly completed, potentially requiring a restart from the
beginning.
• Maintains strong dependencies between steps, meaning that each phase relies heavily on the correct execution of the previous one. This
can create delays or issues if earlier phases were not executed properly.

8
3.4 Prototyping Life Cycle
The Prototyping Life Cycle was developed to reduce the risk of restarting the project due to incomplete, contradictory, or ambiguous requirements
in the initial requirement document. In this approach, the development team first meets with the client to conduct a needs analysis and create
the initial requirement document. Then, a small prototype is developed and presented to the client for feedback. This process helps clarify the
client’s needs, improve understanding, and refine the requirements document. The cycle of developing and reviewing prototypes continues until
the requirements document is fully defined and clear. Once finalized, the project proceeds through the remaining steps of the chosen life cycle
model.

Should We Discard the Prototype or Build Upon It?


The decision depends on several factors. If the prototype was quickly assembled and lacks scalability or if adding new features proves
to be complex due to a poorly thought-out design, it might be more efficient to discard the prototype and start fresh.

However, if the prototype was designed with a solid foundation and can easily accommodate additional features, continuing to build on
it could save time and resources.

Definition & Needs Analysis

Updating RD Client
& Prototype Feedback

Prototype Creation

Completed RD
& Prototype

Rest Of The Life Cycle

3.4.1 Pros
• Reduces the risk of restarting the project due to continuous client feedback, as a complete requirements document is established upfront.

9
3.4.2 Cons
• Creates uncertainty about whether to discard the prototype or continue building on it, which can be time-consuming and resource-intensive.
• Carries the cons of the used life cycle

3.5 Incremental Life Cycle


The Incremental Life Cycle is an iterative model designed to address the uncertainty of whether to discard the prototype or continue building
on it. In this model, development starts with the implementation of a core set of essential features, known as the core increment or the first
increment. This initial increment is delivered to the user for feedback. Subsequent increments, each containing additional features, are built on
top of the core increment and are also sent to the client for review. This process continues iteratively, with feedback shaping the development,
until the project is fully completed.

Importance Of Selecting The Core Features


It is crucial to carefully select the first set of features when implementing the core increment. If this initial set is not scalable, it will be
difficult for developers to add new features and continue building upon it effectively.

Incr3

Incr6

Core Increment

(Incr1 )
Incr7 Incr2

Incr4 Incr5

3.5.1 Pros
• Dividing the project into smaller sets of features makes it easier for developers to manage and focus on one increment at a time.
• Constant client feedback throughout the development process ensures that adjustments can be made as new features are added.
• Minimizes the risk of wasted effort, as nothing is discarded—each increment builds upon the previous one.

10
3.5.2 Cons
• There is a risk of restarting the project if the developers do not select the right initial set of features for the core increment, as future
increments depend on this foundation.
• Each increment inherits the flaws or limitations of the chosen life cycle model.

3.6 Spiral Life Cycle


The Spiral Life Cycle is an iterative model designed for large-scale projects, with a strong focus on risk assessment and mitigation throughout
the development process. It is called ”spiral” because it involves multiple phases arranged in a spiral pattern, with each loop in the spiral
representing a phase of the software development process (an iteration).

• Planning(Objective): The project’s objectives are identified, and alternatives and constraints are defined. High-level requirements
gathering (Needs Analysis) is also performed.
• Risk Analysis(Risk Management): This phase focuses on evaluating risks, uncertainties, and potential problems of the current
iteration, ensuring that risks and strategies to mitigate them are identified early on.
• Engineering (Development & Testing): The actual designing, development, and testing of the product occur in this phase, which
includes activities such as unit testing and integration testing.
• Evaluation(Planning next itteration): After each iteration (loop) of the spiral, there’s an evaluation of the product by the customer
or stakeholders. Feedback is collected, and necessary changes are made before the next loop begins, allowing for continuous improvement
throughout the project.

11
2.Risk Management 1.Planning

3.Engineering 4.Evaluation

3.6.1 Pros
• Continuous client feedback facilitates timely adjustments and improvements to the project.
• Regular identification and assessment of risks, along with strategies for mitigation, help ensure a smoother development process.

3.6.2 Cons
• The model can be complex and challenging to implement effectively, requiring careful planning and coordination.
• It can be resource-intensive, potentially demanding significant time and effort from the development team.

12
3.7 Hybrid Life Cycle
The Hybrid Life Cycle involves dividing the project into n parts, where each parti follows its corresponding lifeCyclei .This model provides the
greatest flexibility among all the methodologies discussed so far.

The Project

Part1 Part5 Partn

Life Cycle1 Life Cycle5 Life Cyclen

Difference Between Incremental & Spiral & Hybrid ?


• Hybrid: This model divides the project into n parts, each with its own life cycle. One of these life cycles can be Incremental or
Spiral.

• Incremental: This approach breaks the project into a set of features called increments, building each subsequent increment on the
core increment.
• Spiral: The Spiral model follows an iterative loop structure, where each loop consists of four steps: Planning, Risk Analysis,
Development & Testing, and Evaluation.

13
3.7.1 Pros
• Offers significant flexibility since each part can adopt a different life cycle model tailored to its specific needs and requirements, enabling
teams to capitalize on the strengths of various methodologies.

3.7.2 Cons
• Can be complex to manage, as coordinating different life cycles for various parts of the project may require additional resources and effort.

• Potential for misalignment between parts if communication and integration aren’t carefully managed, which could lead to inconsistencies
in the overall project.

Difference Between The Life Cycles ?


All the life cycles we’ve reviewed so far include similar steps (activities), the differences arise in the logical and chronological sequencing
of these activities.

14
4 Needs Analysis
A thorough needs analysis is critical in software development. Any ambiguity, contradiction, or missing information found in the requirements
document can lead to significant setbacks, potentially requiring a restart of the project. In this section, we will take a detailed look at how the
requirements document is structured.

Difference Between Goals & Needs ?


It is crucial to understand that the requirements document holds the client’s needs and not their goals . A goal is subjective and open
to interpretation, while a need is objective—measurable or verifiable.

Example :

The client might request a ”pleasant user interface” , This can be interpreted in many ways:

• a visually appealing UI with lots of colors and animations


• an easy-to-use interface
• a minimalistic design

and so on. To turn this into a clear need, we must clarify what the client means. For instance, they might want the UI to be organized
with all features accessible through a dropdown menu.

4.1 Requirments Document Structure


• Introduction : This section provides an overview of the document by outlining its key components :
– Purpose: The reason for creating this document, which is primarily to align the development team and facilitate communication with
the client.

– Scope: A high-level summary of the software’s main functionality, without going into too much detail.

– Context: The reason for creating the software, which could be to sell it to a client or company, to develop an open-source project, or
other similar motivations.

• Hardware : This section states whether the software requires any special hardware components like : GPU, sensors, or a camera ...etc
. It also outlines the minimum hardware requirements needed to run the software, as well as the optimal hardware configuration for the
best and smoothest experience.
• Conceptual Model : This section describes the overall software architecture through a high-level graphical representation, highlighting
key components and their relationships. It provides an overview of how the system is structured and operates, making it easier for
stakeholders to understand.
Example :
A desktop system composed of an email service, a spreadsheet, a document processing service, and an information retrieval service.

15
User

Document
Processing
Email
Management
Information
Retrieval

Network

Spreadsheet DB

The next step consist into creating a new conceptual model for each complexe fonction

User

Message
Creation Document
Spreadsheet
Processing

Message
Deletion

Message
Transfer

Network

16
• Functional Requirements: These define what the system should do, focusing on the specific features and functions the software must
deliver to meet user or business needs. They describe the expected behavior of the system in various situations. Functional requirements
are concrete and measurable. They can be expressed using natural, semi-formal, or formal language, or a mix of these.

– Natural Language: Easy to implement and understand, but lacks structure and precision, which can lead to ambiguity. It makes
automating analysis of the document harder, relying heavily on the writer’s linguistic experience.
– Structured (Semi-Formal) Language: Limited use of natural language, more structured and precise than natural language ,
often accompanied by graphical notations.
– Formal Language: Hard to master and time-consuming to implement. It is difficult for clients to understand but is based on
mathematical theory, making it the most precise language and easier to automate verification.

• Non-Functional Requirements: Define the restrictions and constraints related to both hardware and software within the context of
the ongoing project. Non-functional requirements are particularly influenced by changes in technologies (both hardware and software) and
are crucial for complex software systems. As the project develops, changes in hardware may occur. These changes can be anticipated by
projecting the expected performance levels that will be required by the end of the project.
• Maintenance Information: Anticipates possible actions after the software’s initial release, such as adding new features, improving
performance, or addressing potential issues.
• Glossary: Provides definitions of the terms and concepts used in the document to help readers. This ensures that the terminology is clear,
as the requirements document is shared and read by the design team, developers, and stakeholders, without assuming prior knowledge of
these terms.
• Index: Helps the reader find specific topics and sections of the document more efficiently by providing a detailed list of references to
relevant sections, parts, and page numbers.

Relation Between Functional & Non-Functional Requirements


Functional and non-functional requirements are inherently connected, and their interplay can sometimes lead to conflicts. By under-
standing the potential for these conflicts and establishing a process for managing them, development teams can better balance user needs
and system performance, ultimately leading to a more successful product.

4.2 Requirements Validation


The requirements need to be coherent, realizable, and complete. Anticipation of hardware needs to be considered. It is crucial for the requirements
document to be validated in order to initiate the next steps of the software life cycle.

• review Technique is an efficient way to monitor and update the requirements .


• There are various analysis tools available that can facilitate the validation process of the requirements document, helping to ensure accuracy
and completeness.

17
5 UML
5.1 Introduction
As seen in the previous sections, the requirements document is very important, as any mistake, ambiguity, or misunderstanding of the client’s
needs can lead to a project restart. We’ve reviewed the high-level structure of a requirements document; one of the most important parts is the
functional requirements, which can be expressed in natural language. This approach is easy to implement and understand but isn’t very precise,
doesn’t automate verification, and relies solely on the linguistic experience of the writer. There is also a formal approach based on mathematical
theory, which automates verification, is very precise, but is hard to master and time-consuming. Finally, there is a semi-formal approach that
benefits from the advantages of both natural and formal language; an example of this is UML (Unified Modeling Language).

5.2 UML(Unified Modeling Language)


UML is a semi-formal language that is easy to understand and widely used by developers. It divides into two main categories of diagrams:
• Structure Diagram : Represent the static aspects of a system, showing its classes, objects, and relationships.
• Behaviour Diagram : Describes the dynamic aspects of a system, illustrating how actors interact with the system and how the system
changes over time.
In this section we will focus on Use case diagram

Diagram

Structure Behaviour
Diagram Diagram

Class Component Object Activity Use Case


Diagram Diagram Diagram Diagram Diagram

Profile Composite Deployment Package Interaction State Machine


Diagram Structure Diagram Diagram Diagram Diagram Diagram

Sequence Communication Interaction Timing


Diagram On Diagram Overview Diagram Diagram

18
5.3 Use Case Diagram
A use case diagram is a graphical representation of a behavior diagram, composed of three main elements:

• Actors: Actors represent roles that interact with the system. Each actor performs a set of actions called use cases, which represent features
of the software they interact with. Actors are depicted as stick figures and can be either human or non-human.
– Human actors: Individuals using the system.
– Non-human actors: Entities such as hardware (e.g., sensors, cameras) or software (e.g., APIs, dependencies).
• Use Cases (Features): These represent features or functions of the software and are shown as ellipses , they have to be programmable.
• Associations: Associations are the connections between actors and use cases, depicted as lines. These lines indicate what action (use case)
each actor can perform.

Example:

View Billing Statements Use Case

Actor
Place Order Print Logistic Report
Customer

Association
Cancel Order Arrange Delivery
Logistic Departement Manager

Create Customer Order Generate Statistic Report


Customer Service Assistant Regional Manager

Internal & External Actors


In a use case diagram all actors have to be internal to the software and all use cases must be features from the software that are
programmable
• Internal Actor : must interact with the software

• External Actor : don’t interact with the software

19
The Ideal Level Of Decomposition Of Use Cases
In a use case diagram, the level of decomposition for use cases should strike a balance. It shouldn’t be too specific, as this can make the
diagram cluttered and difficult to read, nor too generic, which can make it hard to understand. A moderate level of detail is ideal.
It’s acceptable to leave some use cases at a more generic level without decomposing them, especially since the diagram is accompanied
by a document that provides detailed explanations. This document defines and elaborates on all sub-use cases as needed.

5.3.1 Relations In Use Case Diagram


• Generalization: Generalization establishes a hierarchical relationship that helps organize actors and use cases in UML diagrams.
– Between Actors: When a child actor is linked to a parent actor, it inherits all the roles and responsibilities of the parent actor,in
addition to its own specific roles. This helps clarify who can perform what actions in the system.

– Between Use Cases: Allows a feature to be divided into multiple, more specific versions. These child use cases represent the same
general feature but can differ in their implementation or method. This promotes reusability and clarity in how features are handled
in different scenarios.

Parent User Case

child User Case 1 child User Case 2 child User Case 3

• Inclusion: This relationship applies only between use cases. The destination use case must execute before the source use case whenever
the source use case is invoked.

”include”
Source Destination

20
• Extension: This relationship applies only between use cases. Before executing the destination use case, a specific condition is checked. If
the condition is met, the source use case will execute before the destination use case.

”extend”
Source Destination

Example:
Let’s Take the example of a bank application

Generalisation Between Use Cases:


the diagram below shows a generalisation relationship between use case where the main feature is transfert that is divided into specific method
and way of achieving the transfert (ATM,Manual,Online)

Transfer

Manual transfer Online transfer ATM transfer

Generalisation Between Actors:


the diagram below shows a generalisation relationship between Actors where the child actor Service Manager is inheriting all roles of the parent
actor teller + his own roles

Teller

Service Manager

inclusion Between Use Cases:


the diagram below shows an inclusion relationship between use cases where each time the transfert case is invoked the identification case must
execute first

”include”
Transfert Identification

21
Extension Between Use Cases:
the diagram below shows an extension relationship between use cases where each time the transfert case is invoked the balance check case will
be executed if the value is >= 10000 DA

”extend”
Balance Check Transfert

If value >=10000DA

Difference Between Inclusion & Extension


In The inclusion relation the Destination case will always execute before source case in all cases , whereas in the extension relation the
source case will execute before destination source only if certain conditions are met

5.4 Class Diagram

What’s a Class Diagram


A Class Diagram is a graphical representation of a structure diagram that illustrates classes, their attributes, and the relationships
between them. It consists of three main components:
• UML Elements: Classes , enumeration , interfaces.
• Relations: Connections that define how classes interact with each other.

• Cardinalities: Numerical indicators of the relationships between classes.


Each component will be explained in detail.

22
5.4.1 UML Elements

Class
Each class is represented as a rectangle containing the following components:
• Class Name: Displayed at the top of the rectangle. It may have an access modifier and other modifiers:
– +: Public
– -: Private
– #: Protected
– (no symbol): Default (Package-private)
– static: Inner class (indicating that the class can exist without an instance of the outer class)
– final: The class cannot be subclassed (i.e., it is a non-extendable class)
– abstract: The class cannot be instantiated directly (i.e., it is intended to be subclassed)

• Attributes: Attributes include both methods and variables of the class. Each method or variable has can have an access modifier
and other modifiers:
– Variables:
∗ +: Public
∗ -: Private
∗ #: Protected
∗ (no symbol): Default (Package-private)
∗ static: The variable belongs to the class, not to instances. It is shared by all instances and has the same value for every
instance.
∗ final: The variable can only be assigned a value once and cannot be modified afterward.
– Methods:
∗ +: Public
∗ -: Private
∗ #: Protected
∗ (no symbol): Default (Package-private)
∗ static: The method can be accessed without creating an instance of the class.
∗ final: The method cannot be overridden by subclasses.
∗ abstract: The method has no implementation in the class and must be implemented by subclasses.

Enumeration
Enumerations are represented in a rectangle as well. The top displays ≪ Enumeration ≫ enumName . Below that, the rectangle holds
the possible values of the enum. it is placed next to the class that uses the enum

23
Interface
Interfaces are represented in a rectangle as well. The top displays ≪ Interface ≫ interfaceName. Below that there are the constant and
method prototypes of the interface it is linked to classes that implements it using the realization relation

Example :
UML :

<<Enumeration>> + Vehicle
VehicleType
Model: String <<Interface>>
Type : VehicleType Drivable
CAR
TRUCK
+ Vehicle(Model :String, Type:VehicleType) drive()
MOTORCYCLE

Note
When class implements an interface there is no need to list the implemented methods

Java Code :
Vehicle Class :

1 public class Vehicle implements Drivable {


2
3 String Model ;
4 VehicleType Type ;
5
6 public Vehicle ( String Model , VehicleType Type ) {
7 this . Model = Model ;
8 this . Type = Type ;
9 }
10
11 @Override
12 public void drive () {
13 System . out . println ( " The " + this . Type . toString () . toLowerCase () + " is driving . " ) ;
14 }
15
16 }

24
VehicleType Enumeration :

1 public enum VehicleType {


2 CAR , TRUCK , MOTORCYCLE ;
3 }

Drivable Interface :

1 public interface Drivable {


2 void drive () ;
3 }

5.4.2 Cardinalities

Cardinality
Cardinality in UML defines the number of instances of one class that can or must be associated with an instance of another class. It
helps indicate the number of objects involved in aggregation , association, compostion relation.
How to Read Cardinality:
Cardinality is represented by numbers near a class, The format is typically ‘min..max‘ , so if there is association between student and
teacher , cardinality near to teacher would be how many instance of teacher for 1 student , and cardinality near student class would be
how many instance of student for 1 teacher
Examples:
• ‘1‘ means exactly one instance.
• ‘0..1‘ means zero or one instance.

• ‘0..*‘ means zero or more instances (unlimited).


• ‘1..*‘ means one or more instances (unlimited).

25
5.4.3 Relations Between Class
Simple Relation(Association)

Association
Association is represented as a solid line between classes. It indicates that one class references another. There are several types of
associations:
• Reflexive Association: A class references itself.
• Unidirectional Association: One class references another class, but the reverse is not true.

• Bidirectional Association: Two classes reference each other.


• N-ary Association: An association involving more than two classes.
• Association Class: The association between classes is created through separate class that references the participating classes
and may include additional attributes or behaviors , it is represented by dashed line connecting between association class and solid
line association.

Note
There is no need to explicitly list references of the other classes in the class association because it is implicitly implied

Example :
Reflexive Association
Employee class that references itself to have a supervisor or manager , so an employee is managed by one manager , and a manager manages
many employees

UML

1..*
is managed by
+ Employee

firstName: String
lastName : String
ID : int
Manager : Employee
1..1
+ Employee(firstName: String, lastName: String, ID: int, Manager: Employee )

26
Employee Class

1 public class Employee {


2
3 String firstName ;
4 String lastName ;
5 int ID ;
6 Employee Manager ;
7
8 public Employee ( String firstName , String lastName , int ID , Employee Manager ) {
9 this . firstName = firstName ;
10 this . lastName = lastName ;
11 this . ID = ID ;
12 this . Manager = Manager ;
13 }
14
15 }

Uni-direction Association
UML

+ Address + Person
country: String firstName: String
state: String 1 1..*
lastName: String
city: String address: Address
street: String associated to
+ Person(firstName: String, lastName: String, address: Address)
+ Address(country: String, state: String, city: String, street: String)

Java Code
Person Class

1 public class Person {


2
3 String firstName ;
4 String lastName ;
5 Address address ;
6
7 public Person ( String firstName , String lastName , Address address ) {
8 this . firstName = firstName ;
9 this . lastName = lastName ;
10 this . address = address ;
11 }
12
13 }

27
Address Class

1 public class Address {


2 String country ;
3 String state ;
4 String city ;
5 String street ;
6
7 public Address ( String country , String state , String city , String street ) {
8 this . country = country ;
9 this . state = state ;
10 this . city = city ;
11 this . street = street ;
12 }
13
14 }

Bi-direction Association
UML

+ Teacher + Article

firstName: String title: String


lastName: String description: String
1..* 0..*
ID: int writerList: Set<Teacher>
articleList: Set<Article> write
+ Article(title: String, description: String, writerList Set<Teacher>)
+ Teacher(firstName: String, lastName: String, ID: int) + cancelArticle()
+ addArticle(article: Article) + addTeacher(teacher: Teacher)
+ removeArticle(article: Article) + removeTeacher(teacher: Teacher)

Java Code
Teacher Class
1 import java . util . LinkedHashSet ;
2 import java . util . Set ;
3
4 public class Teacher {
5 String firstName ;
6 String lastName ;
7 int ID ;
8 Set < Article > articleList = new LinkedHashSet < >() ;
9
10 public Teacher ( String firstName , String lastName , int ID ) {
11 this . firstName = firstName ;
12 this . lastName = lastName ;
13 this . ID = ID ;
14 }
15
16 public void addArticle ( Article article ) { this . articleList . add ( article ) ;}
17 public void removeArticle ( Article article ) { this . articleList . remove ( article ) ;}
18 }

28
Article Class

1 import java . util . LinkedHashSet ;


2 import java . util . Set ;
3
4 public class Article {
5 String title ;
6 String description ;
7 Set < Teacher > writerList = new LinkedHashSet < >() ;
8
9 public Article ( String title , String description , Set < Teacher > writerList ) {
10 if ( writerList == null || writerList . isEmpty () ) {
11 throw new I l l e g a l A r g u m e n t E x c e p t i o n ( " Error Article Must Have At Least One Writer " ) ;
12 }
13 this . title = title ;
14 this . description = description ;
15
16 for ( Teacher teacher : writerList ) {
17 this . addTeacher ( teacher ) ;
18 }
19
20 }
21
22 public void cancelArticle () {
23 for ( Teacher teacher : this . writerList ) {
24 this . removeTeacher ( teacher ) ;
25 }
26 }
27
28 public void addTeacher ( Teacher teacher ) {
29 if ( this . writerList . add ( teacher ) ) {
30 teacher . addArticle ( this ) ;
31 }
32 }
33
34 public void removeTeacher ( Teacher teacher ) {
35 if ( this . writerList . remove ( teacher ) ) {
36 teacher . removeArticle ( this ) ;
37 }
38 }
39
40 }

29
Association Class
UML

+ Organization
+ Person
ID: int
firstName: String
1..* 0..* name: String
lastName: String
address: String
address: String
employeList: Map<Integer,Person>
workingList: Set<WorkFor>

+ person(firstName: String, lastName: String, address: String) + Organization(ID: int, name: String, address: String)
+ printEmploye(organizationID: int) + addEmployee(IDemp: int, employe: Person): boolean
+ removeEmployee(IDemp: int): boolean
+ searchEmployee(IDemp: int)

+ WorkFor

salary: double
hiringDate: Date
empID: int

Person Class

1 import java . util . LinkedHashSet ;


2 import java . util . Set ;
3
4 public class Person {
5 String firstName ;
6 String lastName ;
7 String address ;
8 Set < WorkFor > workingList = new LinkedHashSet < >() ;
9
10 public Person ( String firstName , String lastName , String address ) {
11 this . firstName = firstName ;
12 this . lastName = lastName ;
13 this . address = address ;
14 }
15
16 public void printEmploye ( int org anizatio nID ) {
17 for ( WorkFor work : workingList ) {
18 if ( work . organization . ID == organi zationID ) {
19 System . out . println ( " First Name " + this . firstName ) ;
20 System . out . println ( " Last Name " + this . lastName ) ;
21 System . out . println ( " Address " + this . address ) ;
22 System . out . println ( " Salary : " + work . salary ) ;
23 System . out . println ( " Hiring Date " + work . hiringDate ) ;
24 break ;
25 }
26 }}
27 }

30
Organization Class

1 import java . util . HashMap ;


2 import java . util . Map ;
3
4 public class Organization {
5 int ID ;
6 String name ;
7 String address ;
8 Map < Integer , Person > employeList = new HashMap < >() ;
9
10 public Organization ( int ID , String name , String address ) {
11 this . ID = ID ;
12 this . name = name ;
13 this . address = address ;
14 }
15
16 public boolean addEmployee ( int empID , Person employe ) {
17 if (! employeList . containsKey ( empID ) ) {
18 employeList . put ( empID , employe ) ;
19 return true ;
20 } else {
21 System . out . println ( " Employee with ID " + empID + " already exists . " ) ;
22 return false ;
23 }
24 }
25
26 public boolean remov eEmploye e ( int empID ) {
27 if (! employeList . containsKey ( empID ) ) {
28 System . out . println ( " Employee with ID " + empID + " doesn ’t exists . " ) ;
29 return false ;
30 } else {
31 this . employeList . remove ( empID ) ;
32 return true ;
33 }
34 }
35
36
37 public void searchEmploye ( int empID ) {
38 Person employee = employeList . get ( empID ) ;
39
40 if ( employee != null ) {
41 employee . printEmploye ( this . ID ) ;
42 } else {
43 System . out . println ( " Employee Not Found " ) ;
44 }
45 }
46
47
48
49 }

31
WorkFor Class

1 import java . util . Date ;


2
3 public class WorkFor {
4 Organization organization ;
5 Person employe ;
6 double salary ;
7 Date hiringDate ;
8 int empID ;
9
10
11 public WorkFor ( int empID , Organization organization , Person employe , float salary , Date hiringDate ) {
12 this . empID = empID ;
13 this . organization = organization ;
14 this . employe = employe ;
15 this . salary = salary ;
16 this . hiringDate = hiringDate ;
17 if ( organization . addEmployee ( empID , employe ) ) {
18 employe . workingList . add ( this ) ;
19 }
20 }
21
22 }

32
3-ary Association
UML

+ Student

studentName: String
studentID: int

+ Student(name: String, ID: int)

0..*

+ Instructor + Enrollment
0..*
instrutorName: String hour: int
instructorID: int classRoom: String
+ Instructor(name: String, ID: int)

1..*

+ Course

courseName: String
courseID: int

+ Course(name: String, ID: int)

Java Code
Course Class

1 public class Course {


2 String courseName ;
3 int courseID ;
4
5 public Course ( String name , int ID ) {
6 this . courseName = name ;
7 this . courseID = ID ;
8 }
9 }

33
Instructor Class

1 public class Instructor {


2 String instr uctorNam e ;
3 int instructorID ;
4
5 public Instructor ( String name , int ID ) {
6 this . in structor Name = name ;
7 this . instructorID = ID ;
8 }
9 }

Student Class

1 public class Student {


2
3 String studentName ;
4 int studentID ;
5
6 public Student ( String name , int ID ) {
7 this . studentName = name ;
8 this . studentID = ID ;
9 }
10
11 }

Enrollment Class

1 import java . util . LinkedHashSet ;


2 import java . util . Set ;
3
4 public class Enrollment {
5 Set < Student > studentList = new LinkedHashSet < >() ;
6 Set < Instructor > ins tructorL ist = new LinkedHashSet < >() ;
7 Course course ;
8 int hour ;
9 String classRoom ;
10
11 public Enrollment ( Set < Student > stdList , Set < Instructor > instList , Course course , int hour , String classRoom ) {
12 if ( stdList == null || stdList . isEmpty () ) {
13 throw new I l l e g a l A r g u m e n t E x c e p t i o n ( " Error Can ’t Course With 0 Students " ) ;
14 }
15 else if ( instList == null || instList . isEmpty () ) {
16 throw new I l l e g a l A r g u m e n t E x c e p t i o n ( " Error Can ’t Course With 0 Teachers " ) ;
17 }
18 this . studentList = stdList ;
19 this . in structor List = instList ;
20 this . course = course ;
21 this . hour = hour ;
22 this . classRoom = classRoom ;
23 }
24
25 }

34
Dependency

Dependency
A dependency is represented by a dashed line with an arrow pointing to the provider class. It indicates a temporary relationship
between two classes, where one class relies on the other to perform a specific function or operation. The types of dependency include:

• Method Call: One class calls a method of another class without retaining a permanent reference.
• Object Usage: One class temporarily interacts with an object of another class, either as:
– method parameter.
– return type.

Difference Between Association & Dependency


A dependency is a weaker relationship compared to an association. Unlike an association, which represents a permanent structural
relationship (e.g., an instance variable), a dependency represents a temporary interaction.
In a dependency:

• The referenced object is used only temporarily and is eligible for garbage collection once the interaction ends.
• The classes are loosely coupled, meaning changes to one class have a lower impact on the other.
In contrast, an association involves a permanent reference to another class that exists as long as the object itself exists.

Example
Method Call
UML

+ Document + Printer

+ printDocument() + printMessage(message: String)

Printer Class

1 public class Printer {


2 public void printMessage ( String message ) {
3 System . out . println ( " Printer : " + message ) ;
4 }
5 }

35
Document Class

1 public class Document {


2 public void printDocument () {
3 Printer printer = new Printer () ;
4 printer . printMessage ( " Printing the document ... " ) ;
5 }
6 }

Object Parameter In Method


UML

+ Email
+ EmailService
subject: String
+ sendEmail(email: Email)
+ Email(subject: String)

Email Class

1 public class Email {


2
3 String subject ;
4
5 public Email ( String subject ) {
6 this . subject = subject ;
7 }
8
9 }

EmailService Class

1 public class EmailService {


2 public void sendEmail ( Email email ) {
3 System . out . println ( " Sending email with subject : " + email . subject ) ;
4 }
5 }

36
Return Type Of A Method
UML

+ Report
+ ReportGenerator
content: String
+ generateReport(content: String): Report
+ Report(content: String)

Report Class

1 public class Report {


2
3 String content ;
4
5 public Report ( String content ) {
6 this . content = content ;
7 }
8
9 }

ReportGenerator Class

1 public class Re p or tG en e ra to r {
2 public Report generat eReport ( String content ) {
3 return new Report ( content ) ;
4 }
5 }

Inheritance

Inheritance
Inheritance occurs when a class extends (inherits from) another class. It is represented in UML by a solid line with a hollow triangle
at the end, pointing to the parent class.

Note
Since the child class inherits all attributes and methods from the parent class, there’s no need to explicitly list them unless a
method is overridden or the visibility of an attribute is changed. The constructor is mentioned in the subclass only if it
takes more parameters than the parent class constructor or if its body contains more than just a call to the parent
constructor.

37
Example
UML

+ Animal

name : String

+ Animal(name: String)
+ sound()

+ Cat
+ Dog
- name: String
+ sound() <<Override>>
+ Cat(name: String)
+ sound() <<Override>>

Animal Class

1 public class Animal {


2 String name ;
3
4 public Animal ( String name ) {
5 this . name = name ;
6 }
7
8 public void sound () {
9 System . out . println ( this . name + " making animal sound " ) ;
10 }
11 }

Cat Class

1 public class Cat extends Animal {


2 private String name ;
3
4 public Cat ( String name ) {
5 super ( name ) ;
6 System . out . println ( " Cat Was Created " ) ;
7 }
8
9 @Override
10 public void sound () { System . out . println ( this . name + " is meowing " ) ; }
11 }

38
Dog Class

1 public class Dog extends Animal {


2
3 public Dog ( String name ) {
4 super ( name ) ;
5 }
6 @Override
7 public void sound () {
8 System . out . println ( this . name + " is barking " ) ;
9 }
10
11 }

Aggregation

Aggregation
Aggregation is a stronger relationship than association. It involves two classes: a whole class and a part class. The whole class references
the part class, but the part class exists independently of the whole class. The part class is unaware of the whole class. Even if the whole
class is destroyed by the garbage collector, the part class continues to exist.

Example
UML

+ Teacher + Department

ID: int 0..* 0..* deptName: String


name: String teachers: Set<Teacher>

+ Teacher(ID: int, name: String) + Departement(deptName: String, teachers: Set<Teacher>)


+ teach() + showTeachers()

Teacher Class

1 public class Teacher {


2
3 String name ;
4 int ID ;
5
6 public Teacher ( String name , int ID ) {
7 this . name = name ;
8 this . ID = ID ;
9 }
10
11 public void teach () {
12 System . out . println ( name + " is teaching . " ) ;
13 }
14 }

39
Department Class

1 import java . util . LinkedHashSet ;


2 import java . util . Set ;
3
4 public class Department {
5 String deptName ;
6 Set < Teacher > teachers = new LinkedHashSet < >() ;
7
8 public Department ( String deptName , Set < Teacher > teachers ) {
9 this . deptName = deptName ;
10 this . teachers = teachers ;
11 }
12
13 public void showTeachers () {
14 System . out . println ( " Teachers in " + deptName + " department : " ) ;
15 for ( Teacher teacher : teachers ) {
16 System . out . println ( " - " + teacher . ID + " " + teacher . name ) ;
17 }
18 }
19 }

Composition

Composition
Composition is a stronger relationship than aggregation. In composition, when the whole class is deleted, the part class is also deleted,
as the part is tightly bound and dependent to the whole.

40
Example
UML

<<Enumeration>>
fileExtension

PDF
WORD
PPTX
TEX

+ Document

name: String
+ Version extension: fileExtension
content: StringBuilder
version: double 0..* 1 versionList: Set<Version>
content: StringBuilder
+ Document(name: String,extension: fileExtension, content: StringBuilder)
+ Version(version: double, content: StringBuilder) + createVersion(version: int)
+ deleteVersion(version: int)
+ revertTo(version: int)
+ deleteDocument(version: int)

Version Class

1 public class Version {


2
3 double version ;
4 StringBuilder content ;
5
6 public Version ( double version , StringBuilder content ) {
7 this . version = version ;
8 this . content = content ;
9 }
10
11 }

fileExtension Enumeration

1 public enum fileExtension {


2 PDF , WORD , PPTX , TEX ;
3 }

41
Document Class

1 import java . util . LinkedHashSet ;


2 import java . util . Set ;
3
4 public class Document {
5
6 String name ;
7 fileExtension extension ;
8 StringBuilder content ;
9 Set < Version > versionList = new LinkedHashSet < >() ;
10
11 public Document ( String name , FileExtension extension , StringBuilder content ) {
12 this . name = name ;
13 this . extension = extension ;
14 this . content = content ;
15 }
16
17 public void createVersion ( int version ) {
18 Version newVersion = new Version ( version , this . content ) ;
19 this . versionList . add ( newVersion ) ;
20 }
21
22 public void deleteVersion ( int version ) {
23 for ( Version ver : this . versionList ) {
24 if ( ver . version == version ) {
25 this . versionList . remove ( ver ) ;
26 System . out . println ( " Successfully Deleted Version : " + version ) ;
27 return ;
28 }
29 }
30
31 System . out . println ( " Version " + version + " Not Found " ) ;
32 }
33
34 public void revertTo ( int version ) {
35
36 for ( Version ver : this . versionList ) {
37 if ( ver . version == version ) {
38 this . content = ver . content ;
39 System . out . println ( " Successfully Reverted To Version : " + version ) ;
40 return ;
41 }
42 }
43
44 System . out . println ( " Version " + version + " Not Found " ) ;
45 }
46
47 public void del eteDocu ment () {
48 versionList . clear () ;
49 }
50
51 }

42
5.5 Summary
Enumeration

<<Enumeration>>
Class1
Enum1
field: enum1
value_1
method(type): type value_2
value_3

Interface

<<Interface>>
Interface1
Class1
field1: Type
field: type
field2: Type
method(type): type
method1(par: Type): Type
method2(): Type

Reflexive Association

card_1

Class1

field: type

card_2 method(type): type

43
Simple Association

Class1 Class2
card_1 card_2
field: type field: type

method(type): type method(type): type

N-ary Association

Class1

field: type

method(type): type

card_1
Class3
card_3

field: type

method(type): type
card_2

Class2

field: type

method(type): type

44
Class Association

Class1 Class2

field: type card_1 card_2 field: type

method(type): type method(type): type

ClassAssociation

field: type

Dependency

dependentClass providerClass

field: type field: type

method(type): type method(type): type

Inheritance

subClass parentClass

field: type field: type

method(type): type method(type): type

Aggregation

partClass wholePart
card_1 card_2
field: type field: type

method(type): type method(type): type

45
Composition

partClass wholePart
card_1 card_2
field: type field: type

method(type): type method(type): type

Note
We can read composition and aggregation as whole class contains part class.

46
6 Conception
6.1 Introduction
Conception Introduction
Conception represents the solution to a problem, expressed through structured diagrams such as UML. Creating a conception is an
iterative process that requires significant time and creativity. Initially, a solution is developed, and subsequent iterations focus on
optimizing it.
Each iteration refines and expands the conception until reaching a final result that is easy to maintain. This ensures better implemen-
tation, facilitates adding or removing features, and simplifies bug fixes.

Difference Between Conception & UML


Conception ̸⇔ UML

UML is merely a tool used to represent the conception, it is not the conception itself. Conception encompasses more than just diagrams—it
includes algorithms, explanations of diagrams, and other documents.

Importance of Maintainability
Easy maintainability is one of the key qualities of a good conception and arguably the most important criteria. This is because we want
the software to be long-lasting, and effective maintenance is essential to achieving that.

6.2 Itterative Process Of Conception

Global & Detailed Conception


• Globale Conception : Modules must be identified (some modules can be divided into sub-modules) , and interaction between
modules must be defined
• Detailed Conception : Each module must be defined independently in detail.

The conception should have high ratio of cohesion and low ratio of coupling

47
Why Global Conception Then Detailed Conception
We first define the high-level structure of the modules and their interactions to provide an overall system architecture. This gives a clear
overview of the software before delving into the detailed characteristics of each module.

Why High Cohesion & Low Coupling


• Cohesion: How related the responsibilities of a module are.

– High Cohesion: The module has a clear, well-defined responsibility, making it easier to understand, maintain, and modify.
– Low Cohesion: The module handles multiple, unrelated responsibilities, making it harder to maintain and understand.
• Coupling: How dependent the modules are on each other.
– High Coupling: Modules are highly dependent on each other. A failure in one critical module may cause the entire system
to fail.
– Low Coupling: Modules are loosely connected, and changes or failures in one module are less likely to impact the others.

Why We Want High Cohesion and Low Coupling:


• High Cohesion: Ensures that each module has a clear, understandable purpose, making the system easier to maintain and extend.
• Low Coupling: Reduces dependencies between modules, minimizing the risk of widespread system failure and increasing flexibility.

6.3 Classification Of Conception Method

6.3.1 Function Oriented Conception

Function-Oriented
The software is structured using a functional paradigm. It is divided into a set of functions that interact with each other. The software
is viewed as a complex main function that is progressively decomposed into smaller, less complex sub-functions. This process continues
until we reach a detailed conception.
Each function has its own local state (local variables), while the software has a global state (global variables) that is shared among all
functions.

48
6.3.2 Object Oriented Conception

Object-Oriented Design
The software is viewed as a collection of encapsulated and independent objects. These objects communicate with each other by sending
messages (method calls).
Each object is identified by its name and encapsulated attributes (variables and methods).

6.3.3 Data Oriented Conception

Data-Oriented
The software’s structure must reflect the structure of the data it traits . Therefore the conception is influenced by the ouput input data.

6.4 Conception’s Principales


To make sure the conception ensures an easily maintainable software we must follow some printcipales :

Principles
• Abstraction: Focuses on the essential characteristics while hiding unnecessary details.

• Modularity: Divides the system into modules with well-defined interactions, adhering to the principle of high cohesion and low
coupling.
• Encapsulation: Hides internal details of a module from other modules.
• Structuring: Ensures a structured conceptions (levels) , we can at least have general & detailed conception.

6.5 Notation For Fonctional Conception

Notation
• Data Flow Diagram (DFD): Shows how data is transformed and passed from one module to another.
• Structure Diagram (SD): A hierarchical diagram that illustrates the structured relationships between the components of the
software.

49
Relation Between DFD & SD
DFD and SD are complementary to each other, working together to clearly describe the functional design of a software system.

6.5.1 DFD

DFD
A DFD diagram consists of four components:

• Transformations: Represented as circles.


• Data: Represented as axis.
• Logical AND: Represented by the symbol *.
• Logical OR: Represented by the symbol +.

D1 D1.1 D1.2
T1 T2
D3
* T3 T4
D2
D3.1 + D3.2

Note
A DFD specifies the operations without detailing how they are performed. Each node in the diagram can be further described with
another DFD, allowing for a hierarchical decomposition of processes.

Example :
A Software that processes a text document by splitting it into individual words. It then checks each word against a dictionary. If the word
exists in the dictionary, it is marked as correct. Otherwise, the software notifies the user and allows them to decide whether the word is valid.
If the user identifies the word as incorrect, it is added to the list of misspelled words. If the user confirms the word is valid, it is added to the
dictionary.

50
DC Split into MSL Legends
words
WL CWL DC : Document
* Update WL: Word List
MSL DCT: Dictionary
* L UMSL
* Verify UIW CWL: Correct Word List
IWL: Incorrect Word List
DCT IWL Notify * UD: User Decision
* UIWL: User Incorrect Word List
UCW MSL: Miss Spelled Word List
L Update UMSL: Updated MSL
DC UCWL: User Correct Word List
UD UDCT
UDCT: Updated DCT

6.5.2 SD

SD
A structure diagram is a hierarchical representation of a system in the form of a tree. It illustrates how the transformation elements of
a Data Flow Diagram (DFD) can be implemented within the hierarchical units of software architecture.

Difference Between SD & DFD


They might seem similar but they serve different purposes and compliment each other , SD shows how the data changes and flows with
the transformation , and DFD focuses on the hiertachy of the software architecture

51
Symboles

Symboles

Unit are reprented as rectangles


Unit Name

To link between units we use simple arrow

To represent data flow, use an arrow with an empty Data Name


circle at the starting end and a pointed arrow at the
other end, indicating the flow direction

Tree Nodes
• Synchronisation Unit : The root node at the top represent the the global idea of the software
• Transformation Unit : The parent node has to point to at least one other units , represent a function of the software
• Input/Output Unit : The leaf node same as parent node just never points to another unit

Note
Synchronisation Unit’s Role
The synchronisation unit (root node) never creates the data it only pass it to other units.
No Link Between Unit Of Same Level
There can be link between units with simple arrow only with units of different level.
SD Level
It’s the number of levels beside the root node (don’t count the synchronisation unit).

52
Synchronisation
Unit

A
X

Z
Z
X

Tranformation
Unit B C D

I I Tranformation Output
d
Unit Unit

E F

Input Output
Unit Unit

Example :
We will take same example of word checker, we will make level 1 SD then level 2 SD

Level 1 SD :

To Correct
UMSL
DC,DCT,MSL

DC WL UDCT
CWL, UD UD
IWL
WL IWL
UD

Update Update
Read Split Verify Notify
Dictionary Miss-Spelled

53
Level 2 SD :

To Correct
DC,DCT,MSL
CWL,
IWL
DC WL
WL

Read Split Verify

IWL
UDCT UD UMSL
UD
UD

Update Update
Notify
Dictionary Miss-Spelled

6.5.3 Sequence Diagram

Sequence Diagram
A sequence diagram illustrates the dynamic behavior of a system over time (notion of time). It visualizes the messages exchanged
between objects/actors and is read from top to bottom.

54
Symboles :

Symboles

ObjectName
Rectangle represent internal object of the software.

Stick figures represent external actor


(people interacting with the software, external
software and hardware).
actorName

Vertical dotted line are life line that represents the


time span of an object/actor its life ends with an X.
Destruction

To send a message between an object/actor, we messageName


use a solid line arrow labeled with the message
name.

To send a return message between an returnName


object/actor, we use a dotted line arrow labeled
with the return value or acknowledgment.

To create an object , we use a solid line creation


arrow labeled with Creation , pointing to the newly ObjectName
created object.

sendingMessage
A horizontal rectangle represents the activation
of an object or actor, indicating when it is Self
performing a task. During this time, the object can Call
returnMessage
send messages, receive responses, and make
self-calls.

55
Example :

client Product clientCategory


commercial

Qoute Demand
Calculating Price
purchase
verification

Calculating Sold

Qoute

Creation Object

Destruction
acknowledgment
X

6.5.4 State-Transition Diagram

State Diagram
A state diagram illustrates how the state of an object changes in response to events.

56
Symboles :

Symboles

Filled circle represent the initial state


labeled with its name
state Name

A circle with smaller circle inside represent


the final state labeled with its name state Name

Rounded Rectangle represent a state and State Name


labeled with its name

A solid line arrow connecting between states


represents a transition between states, labeled with an eventName [condition]
event name (event) that triggers the transition and may
include a condition within square brackets [ ],
specifying when the transition occurs.

Note
We can have only one initial state , but we can have many final state.

57
Example :

]
em
command

bl
ro
delivered

oP
[N
ed
er
liv
De
expedition [nbObj>20]
Command in Command in
preparation delivery
initial Ca
nc Lo
state ele
d[
st
[P
nb ro
Ob bl
j<=
20 em
] ]

Canceled
command Lost
command

6.5.5 Activity Diagram

Activity Diagram
An activity diagram describes the progression of activities within the system and outlines the logical flow of processes.

58
Symboles :

Symboles

Rectangle represent an object labeled with Object Name [state]


its name and state between [ ]

Rounded Rectangle represent an activity Activity Name

To link between activities or any entity we


use solid arrow line

Diamond can represent a conditional if condition Else


statement , the if on the left side and else
on right side

Diamond can be a point join between the


entities

Hourglass shape wait until a certain


condition is met to proceed to next activity Condition

Fork

To represent parallelism in an activity


diagram, a fork (thick line) splits the flow Activity Name 1 Activity Name 2
into parallel activities, and a join (another
thick line) merges the parallel activities back
into a single flow. Join

To send signal send signalName

To receive signal
receive signalName

Filled circle represent the start of the


activity diagram or a macro

Circle with inner filled circle represent the


end of the activity diagram or a macro

59
Example :

Activity 1

Activity 2

if condition else

Activity 3 Activity 4

Activity 5

60
Commercial Director Stock

Activity 1 Activity 2

If Condition Else Activity 4

Activity 3

Activity 5

Note
• We can have only one begin , but we can have end.

• Even though activity diagram has the notion of state it focuses more on the logical flow of activities of the system.

6.5.6 Design Pattern

Definition
A design pattern describes proven and abstract solutions to recurring problems in software design.

61
Why Proven
Proven solutions have been tested on real projects, ensuring reliability and effectiveness.

Why Abstract
Abstract solutions can be adapted and customized to meet specific needs.

Why Recurring
We want model for recurring problems to address patterns in design problems that repeat across different contexts.

History
The concept of design patterns was first introduced by Christopher Alexander in the field of architecture. It was later adapted to the
field of computer science in 1977.

Categories :
The first influential book on design patterns, Design Patterns: Elements of Reusable Object-Oriented Software by the ”Gang of Four”
(Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides), was published in its second edition in 1995. It presents a collection of 23
design patterns, classified into three categories.

Creational Design Pattern


Addresses issues related to object creation and configuration, such as the Singleton pattern.

Structural Design Pattern


Describes how to structure classes like: The Composite Pattern

62
Behavioral Design Pattern
Focuses on the interaction and communication between objects to define the behavior of an application, such as the Observer pattern.

Note
The design patterns from the ”Gang of Four” are intended for object-oriented design.

Pros:
• Solves recurring problems with proven and reliable solutions.
• Improves quality and speed.
• Design patterns provide a common language for communication between designers.
• Design patterns are independent of implementation languages and sufficiently generic (abstract) to be applied in various situations.

Cons:
• Design patterns need to be mastered and thoroughly studied.

• Design patterns always require adaptation when applied.


• Design patterns can increase the complexity of simple solutions.

63
Some Design Pattern:
Singleton:
Singleton is a creational design pattern that aims to limit the instanciation of the a class to only one object and give global acess to it.

+ Singleton

- instance: Singleton

- Singleton()
+ getInstance(): Singleton

Explication
We first initialize a static private attribut called instance to null , when ever we want to get instance of singleton we call the public static
method getInstance that checks if instance is null if yes it will call the private constructor and in either case it returns the instance

Java Code:

1 public class Singleton {


2 private static Singleton instance = null ;
3
4 private Singleton () {
5 System . out . println ( " Instance Of Singleton " ) ;
6 }
7
8 public static Singleton getInstance () {
9
10 if ( instance == null ) {
11 instance = new Singleton () ;
12 }
13
14 return instance ;
15 }
16
17 }

64
1 public class Main {
2
3 public static void main ( String [] args ) {
4
5 Singleton . getInstance () ;
6 Singleton . getInstance () ;
7 }
8
9 }

Output:

Instance Of Singleton

Example:

+dataBaseManager

- instance: dataBaseManager
- connectionString: String
- user: String
- password: String
- pdb: String
- server: String

- dataBaseManager()
+ getInstance(): dataBaseManager

Java Code:

1 public class Main {


2
3 public static void main ( String [] args ) {
4
5 d at aB as e Ma na ge r dbManager = da t aB as eM a na ge r . getInstance () ;
6 System . out . println ( dbManager . g e t C o n n e c t i o n S t r i n g () ) ;
7 dbManager . setUser ( " Dbaiot " ) ;
8 dbManager . setPassword ( " psw " ) ;
9 System . out . println ( dbManager . g e t C o n n e c t i o n S t r i n g () ) ;
10 dbManager = d at aB a se Ma na g er . getInstance () ;
11
12 }
13
14 }

65
1 public class dataBas e Ma na ge r {
2 private static d a ta Ba s eM an ag e r instance = null ;
3 private String c o n n e c t i o n S t r in g ;
4 private String user = " system " ;
5 private String password = " 1234 " ;
6 private String pdb = " XE " ;
7 private String server = " localhost :1521 " ;
8
9 private dataBaseM an a ge r () {
10 connectionSt r i ng = " system /1234// localhost :1521/ XE " ;
11 System . out . println ( " d at aB as e Ma na ge r Initialized " ) ;
12 }
13
14
15
16 public static dat aB a se Ma na g er getInstance () {
17 if ( instance == null ) {
18 instance = new d a ta Ba se M an ag e r () ;
19 }
20 else {
21 System . out . println ( " Already Initialized " ) ;
22 }
23 return instance ;
24 }
25
26
27 public String g e t C o n n e c t i o n S t r i n g () {
28 return this . c o n n e c t i o n S t r in g ;
29 }
30
31 public String getUser () {
32 return this . user ;
33 }
34
35 public String getPDB () {
36 return this . pdb ;
37 }
38
39 public String getPassword () {
40 return this . password ;
41 }
42
43 public String getServer () {
44 return this . server ;
45 }
46
47 public void setUser ( String user ) {
48 this . connectio n S t r i n g = this . c o n n e c t i o n S t ri n g . replace ( this . user , user ) ;
49 }
50
51 public void setPassword ( String password ) {
52 this . connectio n S t r i n g = this . c o n n e c t i o n S t ri n g . replace ( this . password , password ) ;
53 }
54
55 public void setServer ( String server ) {
56 this . connectio n S t r i n g = this . c o n n e c t i o n S t ri n g . replace ( this . server , server ) ;
57 }
58
59 public void setPDB ( String pdb ) {
60 this . connectio n S t r i n g = this . c o n n e c t i o n S t ri n g . replace ( this . pdb , pdb ) ;
61 }
62
63 }

66
Output:

dataBaseManager Initialized
system /1234// localhost :1521/ XE
Dbaiot / psw // localhost :1521/ XE
Already Initialized

Composite:
The Composite pattern is a structural design pattern that imposes a hierarchical tree structure, consisting of simple elements and composite
elements.

+ Element

+ operation()

+ Leaf + Composite

- elementList: List<Element>
+ operation()

+ operation()
+ add(element: Element)
+ delete(element: Element)

Explication
The Element class serves as an abstract parent class with an unimplemented method, operation(). The Leaf class inherits from Element
and overrides the operation() method to provide its specific implementation. Similarly, the Composite class also inherits from Element
and implements operation(). However, it has an attribute that is a collection of Element objects. This design allows the collection to
hold both simple elements (Leaf) and complex elements (Composite), organizing them into a tree structure.

Note
Element can be an abstract class or an interface both implementations are valid.

67
Java Code:

1 public abstract class Element {


2
3 public Element () {
4
5 }
6
7 public abstract void operation () ;
8 }

1 public class Leaf extends Element {


2
3 @Override
4 public void operation () {
5 System . out . println ( " Leaf Operation " ) ;
6 }
7
8 }

1 import java . util . LinkedList ;


2 import java . util . List ;
3
4 public class Composite extends Element {
5 private List < Element > elementList = new LinkedList < >() ;
6
7 @Override
8 public void operation () {
9 System . out . println ( " Composite Operation " ) ;
10 }
11
12 public void add ( Element element ) {
13 this . elementList . add ( element ) ;
14 }
15
16 public void delete ( Element element ) {
17 this . elementList . remove ( element ) ;
18 }
19
20 public List < Element > get ElementL ist () {
21 return this . elementList ;
22 }
23
24 public void printTree ( int deepness , List < Element > elementList ) {
25 for ( Element element : elementList ) {
26 if ( element instanceof Leaf ) {
27 System . out . println ( " " . repeat ( deepness ) + " Leaf " ) ;
28 }
29
30 else if ( element instanceof Composite ) {
31 ++ deepness ;
32 System . out . println ( " " . repeat ( deepness ) + " Composite " ) ;
33 Composite com = ( Composite ) element ;
34 printTree ( deepness +1 , com . elementList ) ;
35 }
36 }
37 }
38 }

68
1 public class Main {
2
3 public static void main ( String [] args ) {
4 Composite com = new Composite () ;
5
6 Leaf l1 = new Leaf () ;
7 Leaf l2 = new Leaf () ;
8 Leaf l3 = new Leaf () ;
9 Leaf l4 = new Leaf () ;
10 Leaf l5 = new Leaf () ;
11
12 com . add ( l1 ) ;
13 com . add ( l2 ) ;
14
15 Composite comInner1 = new Composite () ;
16 comInner1 . add ( l3 ) ;
17
18 Composite comInner2 = new Composite () ;
19 comInner2 . add ( l4 ) ;
20 comInner2 . add ( l5 ) ;
21
22 comInner1 . add ( comInner2 ) ;
23
24 com . add ( comInner1 ) ;
25
26 for ( Element element : com . g etEleme ntList () ) {
27 element . operation () ;
28 }
29
30 System . out . println ( " \ n " ) ;
31
32 com . printTree (0 , com . getEle mentList () ) ;
33
34 }
35
36 }

Output:

Leaf Operation
Leaf Operation
Composite Operation

Leaf
Leaf

Composite
Leaf
Composite
Leaf
Leaf

69
Graphical Representation Of The Composite

Composite

Leaf Composite Composite

Leaf Leaf Composite Leaf

Leaf Leaf

Example:

+ GeoFrom

+ draw()

+ simpleForm + complexForm

- type: formType - formList: List<GeoForm>

+ draw() + draw()
+ add(form: GeoForm)
+ delete(form: GeoForm)
<<enumeration>>
formType

Line
Circle
Triangle
Square

70
Java Code:

1 public abstract class GeoForm {


2
3 public GeoForm () {
4
5 }
6
7 public abstract void draw () ;
8 }

1 public class simpleForm extends GeoForm {


2
3 private formType type ;
4
5 public simpleForm ( String type ) {
6 type = type . toUpperCase () ;
7 try {
8 formType . valueOf ( type ) ;
9 this . type = formType . valueOf ( type ) ;
10 }
11 catch ( I l l e g a l A r g u m e n t E x c e p t i o n e ) {
12 System . out . println ( e . getMessage () ) ;
13 }
14 }
15
16
17
18 @Override
19 public void draw () {
20 System . out . println ( " Draw " + this . type ) ;
21 }
22
23 public void setType ( String type ) {
24 type = type . toUpperCase () ;
25 try {
26 formType . valueOf ( type ) ;
27 this . type = formType . valueOf ( type ) ;
28 }
29 catch ( I l l e g a l A r g u m e n t E x c e p t i o n e ) {
30 System . out . println ( e . getMessage () ) ;
31 }
32 }
33
34 public formType getType () {
35 return this . type ;
36 }
37
38 }

1 public enum formType {


2 LINE , CIRCLE , SQUARE , TRIANGLE ;
3 }

71
1 import java . util . LinkedList ;
2 import java . util . List ;
3
4 public class complexForm extends GeoForm {
5 private List < GeoForm > formList = new LinkedList < >() ;
6
7 @Override
8 public void draw () {
9 System . out . println ( " Draw Complexe Form " ) ;
10 }
11
12 public void add ( GeoForm form ) {
13 this . formList . add ( form ) ;
14 }
15
16 public void delete ( GeoForm form ) {
17 this . formList . remove ( form ) ;
18 }
19
20 public List < GeoForm > getFormList () {
21 return this . formList ;
22 }
23
24 public void printTree ( int deepness , List < GeoForm > formList ) {
25 for ( GeoForm form : formList ) {
26 if ( form instanceof simpleForm ) {
27 simpleForm sim = ( simpleForm ) form ;
28 System . out . println ( " " . repeat ( deepness ) + sim . getType () ) ;
29 }
30
31 else if ( form instanceof complexForm ) {
32 ++ deepness ;
33 System . out . println ( " " . repeat ( deepness ) + " Complex " ) ;
34 complexForm com = ( complexForm ) form ;
35 printTree ( deepness +1 , com . formList ) ;
36 }
37 }
38 }
39
40 }

72
1 public class Main {
2
3 public static void main ( String [] args ) {
4 simpleForm sim1 = new simpleForm ( " line " ) ;
5 simpleForm sim2 = new simpleForm ( " circle " ) ;
6 simpleForm sim3 = new simpleForm ( " square " ) ;
7 simpleForm sim4 = new simpleForm ( " triangle " ) ;
8
9 complexForm com = new complexForm () ;
10 com . add ( sim1 ) ;
11 com . add ( sim4 ) ;
12
13 complexForm comInner2 = new complexForm () ;
14 comInner2 . add ( sim1 ) ;
15 comInner2 . add ( sim1 ) ;
16
17 complexForm comInner1 = new complexForm () ;
18 comInner1 . add ( sim3 ) ;
19 comInner1 . add ( sim2 ) ;
20
21 comInner1 . add ( comInner2 ) ;
22
23 com . add ( comInner1 ) ;
24
25 for ( GeoForm form : com . getFormList () ) {
26 form . draw () ;
27 }
28
29 System . out . println ( " \ n " ) ;
30
31 com . printTree (0 , com . getFormList () ) ;
32
33
34
35 }
36
37 }

Output:

Draw LINE
Draw TRIANGLE
Draw Complexe Form

LINE
TRIANGLE
Complex
SQUARE
CIRCLE
Complex
LINE
LINE

73
Observer:
The Observer pattern is a behavioral design pattern.It monitors the state of a subject object, and when the state changes, the subject notifies
the observers, which then update accordingly.

+ Subject
+ Observer
- observerList: List<Observer>
+ update(state: String)
+ add(observer: Observer)
+ delete(observer: Observer)
+ notify()

+ concretSubject
+ concretObserver
- state: String

+ update(state: String)
+ getState() : String
+ setState(state: String)

Explication
The Observer is an abstract class that defines an unimplemented method, update(state), which is executed each time the state
changes. The Subject is also an abstract class. It holds a collection of observers and defines unimplemented methods: add(observer),
delete(observer), and notify(). The notify() method calls the update method of each observer when the state changes. A ConcreteOb-
server inherits from Observer and implements the update method. A ConcreteSubject inherits from Subject, overrides all unimplemented
methods, and includes a state attribute with its getter and setter. Whenever the setter is called, the notify() method is invoked within
its body to ensure all observers are updated.

Note
Subject and Observer can be an abstract class or an interface both implementations are valid.

74
Java Code:

1 public abstract class Observer {


2
3 private String name ;
4
5 public Observer ( String name ) {
6 this . name = name ;
7 }
8
9 public abstract void update ( String state ) ;
10
11 public void setName ( String name ) {
12 this . name = name ;
13 }
14
15 public String getName () {
16 return this . name ;
17 }
18
19 }

1 import java . util . LinkedList ;


2 import java . util . List ;
3
4 public abstract class Subject {
5
6 private List < Observer > observerList = new LinkedList < >() ;
7
8 public abstract void add ( Observer observer ) ;
9 public abstract void delete ( Observer observer ) ;
10 public abstract void no t if yO bs e rv er s () ;
11
12 public List < Observer > ge t Ob se rv e rL is t () {
13 return this . observerList ;
14 }
15
16 }

1 public class co n cr et Ob s er ve r extends Observer {


2
3 public c on c re tO bs e rv er ( String name ) {
4 super ( name ) ;
5 }
6
7 @Override
8 public void update ( String state ) {
9 System . out . println ( " Observer " + this . getName () + " New State : " + state ) ;
10 }
11
12 }

75
1 public class c oncretSu bject extends Subject {
2
3 private String state ;
4
5 @Override
6 public void add ( Observer observer ) {
7 this . ge tO b se rv er L is t () . add ( observer ) ;
8
9 }
10
11 @Override
12 public void delete ( Observer observer ) {
13 this . ge tO b se rv er L is t () . remove ( observer ) ;
14 }
15
16 @Override
17 public void no ti f yO bs er v er s () {
18 for ( Observer obs : ge t Ob se rv e rL is t () ) {
19 obs . update ( this . state ) ;
20 }
21 }
22
23 public String getState () {
24 return this . state ;
25 }
26
27 public void setState ( String state ) {
28 this . state = state ;
29 System . out . println ( " Setting state to " + state ) ;
30 n ot if yO b se rv er s () ;
31 }
32
33 }

1 public class Main {


2 public static void main ( String [] args ) {
3
4 concr etSubje ct subject = new co ncretSu bject () ;
5
6 Observer observer1 = new co nc r et Obse r ve r ( " Alice " ) ;
7 Observer observer2 = new co nc r et Obse r ve r ( " Bob " ) ;
8
9 subject . add ( observer1 ) ;
10 subject . add ( observer2 ) ;
11
12 subject . setState ( " State 1 " ) ;
13
14 subject . delete ( observer1 ) ;
15
16 subject . setState ( " State 2 " ) ;
17 }
18 }

76
Output:

Setting state to State 1


Observer Alice New State : State 1
Observer Bob New State : State 1
Setting state to State 2
Observer Bob New State : State 2

Example:

+ Teacher + Student

- studentList: List<Student> - name: String

+ add(student: Student) + update(activity: String)


+ delete(student: Student)
+ notifyStudents()

+ concretSubject

- activity: String + concretStudent

+ getActivity() : String + update(activity: String)


+ setActivity(activity: String)

77
Java Code:

1 public abstract class Student {


2 private String name ;
3
4 public Student ( String name ) {
5 this . name = name ;
6 }
7
8 public abstract void update ( String activity ) ;
9
10 public void setName ( String name ) {
11 this . name = name ;
12 }
13
14 public String getName () {
15 return this . name ;
16 }
17 }

1 import java . util . LinkedList ;


2 import java . util . List ;
3
4 public abstract class Teacher {
5 private List < Student > studentList = new LinkedList < >() ;
6
7 public abstract void add ( Student student ) ;
8 public abstract void delete ( Student student ) ;
9 public abstract void n otifySt udents () ;
10
11 public List < Student > get StudentL ist () {
12 return this . studentList ;
13 }
14 }

1 public class c oncretSt udent extends Student {


2
3 public concr etStuden t ( String name ) {
4 super ( name ) ;
5
6 }
7
8 @Override
9 public void update ( String activity ) {
10 System . out . println ( " Student " + getName () + " changed activity to " + activity ) ;
11 }
12
13 }

78
1 public class c oncretTe acher extends Teacher {
2
3 private String activity ;
4
5 @Override
6 public void add ( Student student ) {
7 getS tudentLi st () . add ( student ) ;
8 }
9
10 @Override
11 public void delete ( Student student ) {
12 getS tudentLi st () . remove ( student ) ;
13 }
14
15 @Override
16 public void not ifyStud ents () {
17 for ( Student student : getS tudentL ist () ) {
18 student . update ( this . activity ) ;
19 }
20 }
21
22 public String getActivity () {
23 return this . activity ;
24 }
25
26 public void setActivity ( String activity ) {
27 this . activity = activity ;
28 System . out . println ( " Teacher Setting Activity To " + activity ) ;
29 notif yStuden ts () ;
30 }
31
32
33 }

1 public class Main {


2
3 public static void main ( String [] args ) {
4 concr etTeach er teacher = new co ncretTe acher () ;
5
6 Student st1 = new co ncretStu dent ( " Zaki " ) ;
7 Student st2 = new co ncretStu dent ( " Rabah " ) ;
8
9 teacher . add ( st1 ) ;
10 teacher . add ( st2 ) ;
11
12
13 teacher . setActivity ( " DW 2 EX1 " ) ;
14
15 teacher . delete ( st2 ) ;
16
17 teacher . setActivity ( " LAB2 " ) ;
18 }
19 }

79
Output:

Setting Activity To DW 2 EX1


Student Zaki changed activity to DW 2 EX1
Student Rabah changed activity to DW 2 EX1
Setting Activity To LAB2
Student Zaki changed activity to LAB2

80

You might also like