0% found this document useful (0 votes)
26 views69 pages

ASM1 Part1

Uploaded by

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

ASM1 Part1

Uploaded by

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

ASSIGNMENT 1 FRONT SHEET

Qualification Pearson BTEC Level 5 Higher National Diploma in Computing

Unit number and title Unit 20: Applied Programming and Design Principles

Submission date 23/07/2024 Date Received 1st submission

Re-submission Date Date Received 2nd submission

Student Name Kiều Huy Hoàng Student ID BH00429

Class SE06201 Assessor name DINH VAN DONG

Student declaration

I certify that the assignment submission is entirely my own work and I fully understand the consequences of plagiarism. I understand that
making a false declaration is a form of malpractice.

Student’s signature Kiều Huy Hoàng

Grading grid

P1 P2 M1 P3 P4 M2 D1
❒ Summative Feedback: ❒ Resubmission Feedback:

Grade: Assessor Signature: Date:


Internal Verifier’s Comments:

Signature & Date:


Table of contents:
I. Introduction:.........................................................................................................................................................6

II. OOP and SOLID principle:.....................................................................................................................................7

2.1. What is OOP ?................................................................................................................................................7

2.2. Basic characteristics of object-oriented programming:.................................................................................8

2.2.1. Encapsulation:........................................................................................................................................8

2.2.2. Inheritance:..........................................................................................................................................10

2.2.3. Polymorphism:......................................................................................................................................11

2.2.4. Abstraction:..........................................................................................................................................13

2.2.5. Applying OOP to the SIMS project:.......................................................................................................15

2.3. Class Relationships:.....................................................................................................................................24

2.3.1. Composition:........................................................................................................................................25

2.3.2. Association:..........................................................................................................................................27

2.3.3. Aggregation:.........................................................................................................................................29

2.4. SOLID principle:...........................................................................................................................................33

2.4.1. What is SOLID principle ?......................................................................................................................33

2.4.2. SRP ( Single Responsibility Principle ):..................................................................................................34

2.4.3. OCP ( Open/Closed Principle ):.............................................................................................................35

2.4.4. LSP ( Liskov Substitution Principle ):.....................................................................................................35

2.4.5. ISP ( Interface Segregation Principle ):.................................................................................................36

1
2.4.6. DIP ( Dependency Inversion Principle ):...............................................................................................37

2.4.7. The importance of SOLID principle in software design:........................................................................38

III. Clean technique and data structure:.................................................................................................................39

3.1. Clean Coding Techniques:............................................................................................................................39

3.1.1. What is clean coding ?.........................................................................................................................39

3.1.2. Naming:................................................................................................................................................40

3.1.3. Modularity:...........................................................................................................................................42

3.1.4. Comments:...........................................................................................................................................43

3.1.5. Consistency:..........................................................................................................................................44

3.2. Impact on Data Structures and Operations:................................................................................................46

IV. Design pattern in practice:................................................................................................................................50

4.1. Overview ASP .NET Core:.............................................................................................................................50

4.2. A use case diagram:.....................................................................................................................................51

4.3. A class diagram:...........................................................................................................................................52

4.4. A package diagram:.....................................................................................................................................53

4.5. An explanation of how SOLID principles have been applied in your team design:......................................54

V. Apply SOLID principle in SIMS application:.........................................................................................................55

5.1. Creational design patterns are used in practices:........................................................................................55

5.1.1. What is Creational DP:..........................................................................................................................55

5.1.2. Apply in my project:..............................................................................................................................56

2
5.2. Structural design patterns are used in practices:.........................................................................................57

5.2.1. What is Structural DP:...........................................................................................................................57

5.2.2. Apply in my project:..............................................................................................................................58

5.3. Behavioural design patterns are used in practices:.....................................................................................59

5.3.1. What is Behavioural DP:.......................................................................................................................59

5.3.2. Apply in my project:..............................................................................................................................60

VI. Analyse the SIMS application and evaluate how adhering to SOLID principles has influenced the design and

development:.........................................................................................................................................................61

6.1. Analyse the SIMS application:.....................................................................................................................61

6.2. Influence of SOLID principles in design and developing SIMS applications:...............................................64

VII. Conclusion:.......................................................................................................................................................66

VIII. References:.....................................................................................................................................................67

3
Table of figure:
Figure 1: Object-oriented programming (OOP)........................................................................................................7

Figure 2: Encapsulation............................................................................................................................................9

Figure 3: Inheritance..............................................................................................................................................10

Figure 4: Polymorphism..........................................................................................................................................12

Figure 5: Abstraction..............................................................................................................................................14

Figure 6: Output Encapsulation..............................................................................................................................18

Figure 7: Output Inheritance..................................................................................................................................20

Figure 8: Output Polymorphism.............................................................................................................................22

Figure 9: Output Abstraction..................................................................................................................................24

Figure 10: Filled Diamond Arrow............................................................................................................................25

Figure 11: Composition Class Relationships...........................................................................................................26

Figure 12: Simple Line............................................................................................................................................27

Figure 13: Association Class Relationships.............................................................................................................28

Figure 14: Empty Diamond Arrow..........................................................................................................................29

Figure 15: Aggregation Class Relationships............................................................................................................30

Figure 16: SOLID principle......................................................................................................................................33

Figure 17: SRP ( Single Responsibility Principle )....................................................................................................34

Figure 18: OCP ( Open/Closed Principle )...............................................................................................................35

Figure 19: LSP ( Liskov Substitution Principle ).......................................................................................................36

Figure 20: ISP ( Interface Segregation Principle )....................................................................................................36

Figure 21: DIP ( Dependency Inversion Principle )..................................................................................................37

Figure 22: Clean Coding Techniques.......................................................................................................................40

Figure 23: ASP .NET Core........................................................................................................................................51

4
Figure 24: A use case diagram................................................................................................................................52

Figure 25: A class diagram......................................................................................................................................53

Figure 26: A package diagram................................................................................................................................53

Figure 27: Creational design patterns.....................................................................................................................56

Figure 28: Structural Design Patterns.....................................................................................................................58

Figure 29: Behavioural design patterns..................................................................................................................60

5
I. Introduction:
Currently, I am a team leader at FPT company. My company FPT was selected to carry out a project to
modernize student information systems for universities that want to improve efficiency and
maintainability. This is a great opportunity for our team. As a team leader, I am responsible for guiding
my team to design and implement robust SIMS that follows object-oriented principles, SOLID
principles, clean coding practices, and is suitable for a variety of designs different. At the same time, I
also lead my team to use technologies, tools and design techniques to implement the system to
enhance and develop the system effectively.

To ensure the project is completed quickly and on schedule, I will provide some useful information in
this report to help you better understand this project so it can be completed. successful and on
schedule. First, I will learn how the object-oriented paradigm works, including the concept of
inheritance, polymorphism, abstraction, encapsulation. Along with that, I will also introduce
association, aggregation, and composition relationships. Finally, SOLID principles and their importance
in software design. After I studied the characteristics of the object-oriented model, including class
relationships and SOLID principles. In the next section, I will explain how clean coding techniques can
impact the use of data structures and operations when writing algorithms. This will create favorable
conditions for expanding and improving the performance of the software. In the next part, I will go
about designing the application's architecture and a suitable testing mode for SIMS. The use of ASP
.NET Core is necessary for the project. Additionally, I will use use case, class, and package diagrams to
better understand this system. At the same time, I will explain how to apply SOLID principles in system
implementation design. Finally, I will design an appropriate testing regime for the application, including
providing automated testing. To do that, I need to define test scope, create test scenarios, and design
automated tests. Then, prepare the test environment and execute the test, record the results, and
optimize to ensure the correctness and performance of the application. This, ensures reliability and
increases development performance, while also creating confidence in the quality of the application.

Please join me to learn more about this project.

6
II. OOP and SOLID principle:
2.1. What is OOP ?

Object-oriented programming (OOP) is a programming paradigm that organizes code around objects,
which are instances of classes. OOP focuses on the objects the developer wants to manipulate rather
than the logic needed to manipulate them. This approach to programming is well suited to programs
that are large, complex, and actively updated or maintained.

When it comes to OOP, we need to pay attention to two main concepts: Object and Class.

- Objects in OOP include: (1) Attributes: information and characteristics of an object; (2) Method:
Actions that an object can perform. More simply, properties describe what properties an object has,
while methods are the means to use that object.

- Class: A class will include objects with similar properties in terms of properties and methods. It can be
said that classes are abstractions of groups of objects.

Figure 1: Object-oriented programming (OOP).

 Basic characteristics of OOP:

- Encapsulation: This is shown by the fact that related objects and methods are packaged into small
classes and built to perform a specific group of functions. This feature also helps hide some
information and internal settings to avoid information leakage to the outside.

7
- Inheritance: As its name suggests, data classes inherit each other. Parent classes can share data and
methods with subclasses, from which subclasses can inherit and add new components of their own.
Some common types of inheritance include: single inheritance, multiple inheritance, multi-level
inheritance, and hierarchical inheritance. This helps programmers save time and effort in programming
classes with similar characteristics.

- Polymorphism: Polymorphism is an action that can be performed in different ways. In simpler terms,
polymorphism is the concept in which multiple classes have the same methods, but are implemented
in different ways.

- Abstraction: Abstraction is when you generalize something and don't pay too much attention to
what's inside. Applied in OOP programming, you choose the properties and methods of the object
needed in programming.

2.2. Basic characteristics of object-oriented programming:

To better understand OOP, in the student information management system (SIMS) project, I will apply
and present the structure and design of a software system based on packaging concepts. , inheritance,
polymorphism and abstraction, and I also give the advantages and disadvantages. At the same time, I
will also choose important elements to apply to this project. This helps me reuse code, extend
features, and create abstractions for easy and consistent system management.

2.2.1. Encapsulation:

Encapsulation is a concept in object-oriented programming (OOP) that allows encapsulation of data


and related methods into an object.

In addition, encapsulation also allows hiding information and internal processing properties of the
object. Other objects cannot directly affect the internal data and change the object's state but must go
through public methods provided by that object. It also helps protect data from direct outside
interference and ensures system accuracy and safety.

8
Figure 2: Encapsulation.

 Advantages and Disadvantages of Encapsulation:

- Advantages of Encapsulation:

Data Hiding: Encapsulation helps hide details within an object and reveal only a well-defined interface.
This helps protect data integrity by preventing direct access and changes from outside the object.

Modularity: Encapsulation promotes modularity by organizing code into independent objects. Each
object can have its own internal settings, making it easier to understand, maintain, and update.

Reusability: Packaging also improves reusability and makes it easier to change to new requirements.
Testable code is easy: Packaged code is easy to test for unit testing.

- Disadvantages of Encapsulation:

Complexity and added work: Packaging can increase the complexity of software system design and
implementation. It requires careful consideration of class structure, relationships, and interfaces.

Indirect access: Encapsulation restricts direct access to an object's internal state, resulting in having to
interact with specific methods or properties to access or change data.

Limited flexibility: Encapsulation can make it more difficult to extend or modify an object's behavior.
Testing and debugging: Encapsulation can increase the complexity of testing and debugging.

9
2.2.2. Inheritance:

Inheritance is an important concept in object-oriented programming, allowing a new class to inherit


properties and methods from an existing class. A new class (subclass) is called a subclass that inherits
from an existing class (superclass).

Subclasses inherit all members of the Superclass and do not need to be redefined. The Child class can
extend inherited components or add new components.

Figure 3: Inheritance.

In addition, inheritance also has 4 types of inheritance:

- Single Inheritance: This is a type of inheritance in which a derived class uniquely inherits from a single
base class. The leading class can use and extend the properties and methods of the class database.

- Multi-level inheritance: The derived class is explicitly designed from the base class and main derived
class to become the base class for another publishing class.

- Hierarchical inheritance: A base class acts as the parent class of two or more leading classes. Each
derived class can inherit the properties and methods of the base class and can also have its own
properties and methods.

- Multiple inheritance: A production class inherits from two or more base classes. The derived class can
use the properties and methods of all the bases it inherits from.

10
 Advantages and Disadvantages of Inheritance:

- Advantages of Inheritance:

Inheritance helps increase reusability. When a class inherits or derives another class, it can access all
the functions of the class it inherits from.

Reusability enhances reliability. We only need to test and debug the parent class code, not each
subclass.

When code is reused, it helps reduce development and maintenance costs. Subclasses will comply with
a standard interface.

Inheritance helps limit code redundancy and supports code extensibility. Programmers have favorable
conditions to create class libraries.

- Disadvantages of Inheritance:

Inherited functions work slower than normal functions, because it is implemented indirectly (taken
from the parent class) and not directly.

Normally, data members in the superclass are not used. This can lead to wasted memory.

Inheritance increases the connection between the base class and the derived class. A change in the
parent class will affect all child classes.

Using Inheritance incorrectly can lead to incorrect solutions later on.

2.2.3. Polymorphism:

Polymorphism is an important concept in object-oriented programming, allowing different objects to


implement the same functionality in different ways. In other words, it can be viewed as an object of its
superclass or subclass.

- There are two types of polymorphism:

11
Compile-time polymorphism: Compile-time polymorphism occurs when the decision to call a method
occurs at compile time based on the data type of the arguments passed or the data type of the calling
object method.

Runtime polymorphism: Runtime polymorphism occurs when deciding which method invocation
occurs at runtime based on the actual type of the object. Runtime polymorphism is often accomplished
through inheritance and method overriding.

Figure 4: Polymorphism.

 Advantages and Disadvantages of Polymorphism:

- Advantages of Polymorphism:

Code flexibility and extensibility: Polymorphism allows objects of different types to be seen as
instances of a common superclass or interface. This gives the flexibility to use a single interface to
represent multiple related classes.

Code Reuse: Polymorphism promotes code reuse by allowing the use of common algorithms and
functions that can operate on different objects.

Simplify code structure: Polymorphism simplifies code structure by hiding the specifics of different
object types. It allows for cleaner and more concise code through an interface or base class.

Flexible and dynamic: Polymorphism supports late binding or dynamic binding, which means that the
specific implementation of a method is determined at runtime based on the actual object type.

12
- Disadvantages of Polymorphism:

Performance overhead: Dynamic method binding and additional abstraction layers can cause
performance overhead.

Increased complexity: While polymorphism can simplify code in a number of ways, it can also make
code more complex and difficult to understand.

Difficult debugging: Polymorphism can make debugging more difficult. Since the actual method that
will be executed is determined at runtime, error tracking can be more complicated than with static
binding.

Reduced compile-time type checking: With polymorphism, some errors that should be detectable at
compile time may only be detected at runtime, increasing the likelihood of errors occurring run time.

2.2.4. Abstraction:

Abstraction is an important concept in object-oriented programming, allowing the creation of abstract


classes, objects, and methods to model real-world concepts, properties, and behaviors.

Abstraction also helps eliminate complex, unnecessary things from the object and focus only on what is
core and important. It helps create abstract objects without knowing the specifics of their internal
implementation. This increases flexibility and ease of maintenance during software development.

The main purpose of abstraction is to provide a general model, a framework for building concrete
subclasses. It helps separate general concepts and behavior from specific objects, and allows extending
and changing the behavior of subclasses without affecting other components in the system.

13
Figure 5: Abstraction.

 Advantages and Disadvantages of Abstraction:

- Advantages of Abstraction:

Simplified code: Abstraction allows developers to work with simpler code by hiding complex details
and exposing only the necessary parts. This makes the code easier to understand and work with.

Enhanced readability and maintainability: By separating implementation details from user objects,
abstraction makes code more readable and easier to maintain.

Modularity: Abstraction helps create a modular code structure. Each module can be developed and
tested independently, which results in more streamlined and organized code.

Improved Reusability: Abstraction promotes code reuse by allowing developers to define common
interfaces for different implementations.

Ease of change: Abstraction makes it easier to change the implementation without affecting other
parts of the code.

14
- Disadvantages of Abstraction:

Performance overhead: Abstraction can cause performance overhead due to the addition of indirect
layers. This can add latency compared to using more direct, low-level methods.

Complexity in understanding: While abstraction simplifies the use of complex systems, it can also make
understanding the system as a whole more difficult.

Design overhead: Poorly designed abstractions can lead to confusion and can complicate the
development process rather than simplify it.

Risk of over-abstraction: There is a risk of over-abstraction, where too many layers of abstraction are
introduced, making the system unnecessarily complex and harder to manage.

Potential for increased code size: Abstraction can lead to increased size of the code base due to the
presence of additional classes and interfaces.

2.2.5. Applying OOP to the SIMS project:

To better understand the concepts, as well as the advantages and disadvantages of OOP features. I will
apply these characteristics in the SIMS project. Here, I will give specific examples when applying it to
the project.

a. Encapsulation:

- Input:

static void Main(string[] args)


{
Student student1 = new Student("John Doe", 20, "S12345");
// Display student information
Console.WriteLine("Student Information:");
student1.DisplayInfo();

// Update student information


student1.Age = 21;
student1.DisplayInfo();

15
// Attempt to set negative age
student1.Age = -5;
Console.ReadLine();
}
class Student
{
// Private fields
private string name;
private int age;
private string studentId;

// Constructor
public Student(string name, int age, string studentId)
{
this.name = name;
this.age = age;
this.studentId = studentId;
}
// Public properties to access private fields
public string Name
{
get { return name; }
set { name = value; }
}
public int Age
{
get { return age; }
set
{
if (value >= 0) // Assuming age cannot be negative
age = value;
else
Console.WriteLine("Age cannot be negative.");
}
}
public string StudentId
{
get { return studentId; }
set { studentId = value; }
}
// Method to display student information
public void DisplayInfo()
{
Console.WriteLine($"Name: {name}");

16
Console.WriteLine($"Age: {age}");
Console.WriteLine($"Student ID: {studentId}");
}
}

- Explain:

Creating a Student Object: Student student1 = new Student("John Doe", 20, "S12345"); creates a new
Student object with the name "John Doe", age 20, and student ID "S12345".

Displaying Information: student1.DisplayInfo(); calls the DisplayInfo method to print the student's
information to the console.

Updating Age: student1.Age = 21; updates the student's age to 21. student1.DisplayInfo(); displays the
updated information.

Attempting to Set Negative Age: student1.Age = -5; attempts to set the age to a negative value, which
triggers a validation check.

Waiting for User Input: Console.ReadLine(); keeps the console window open until the user presses
Enter.

Private Fields: private string name;, private int age;, and private string studentId; store the student's
name, age, and student ID respectively.

Constructor: public Student(string name, int age, string studentId) initializes the fields with the
provided values when a new Student object is created.

Properties: Name: public string Name { get { return name; } set { name = value; } } allows getting and
setting the name field.

Age: public int Age { get { return age; } set { if (value >= 0) age = value; else Console.WriteLine("Age
cannot be negative."); } } allows getting and setting the age field, with a validation check to ensure the
age is not negative.

StudentId: public string StudentId { get { return studentId; } set { studentId = value; } } allows getting
and setting the studentId field.

17
Method: public void DisplayInfo() prints the student's name, age, and student ID to the console.

- Output:

Figure 6: Output Encapsulation.

b. Inheritance:

- Input:

static void Main(string[] args)


{
Student student = new Student();
student.Name = "John Doe";
student.Age = 20;
student.StudentId = "123456";
student.GPA = 3.5;

student.PrintStudentDetails();
Console.ReadLine();
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }

public void PrintDetails()


{
Console.WriteLine($"Name: {Name}");
Console.WriteLine($"Age: {Age}");
}
}

18
public class Student : Person
{
public string StudentId { get; set; }
public double GPA { get; set; }

public void PrintStudentDetails()


{
base.PrintDetails();
Console.WriteLine($"Student ID: {StudentId}");
Console.WriteLine($"GPA: {GPA}");
}
}

- Explain:

Creating a Student Object: Student student = new Student(); creates a new instance of the Student
class.

Setting Properties: student.Name = "John Doe"; sets the Name property inherited from the Person
class. student.Age = 20; sets the Age property inherited from the Person class. student.StudentId =
"123456"; sets the StudentId property specific to the Student class. student.GPA = 3.5; sets the GPA
property specific to the Student class.

Printing Details: student.PrintStudentDetails(); calls the method to print the student's details.

Keeping Console Open: Console.ReadLine(); waits for the user to press Enter before closing the console
window.

Properties: public string Name { get; set; set; } defines a property for the person's name. public int Age
{ get; set; set; } defines a property for the person's age.

Method: public void PrintDetails() prints the Name and Age properties to the console.

Inheritance: public class Student : Person declares that Student inherits from Person, meaning it has all
properties and methods of Person.

Additional Properties: public string StudentId { get; set; set; } defines a property for the student ID.
public double GPA { get; set; set; } defines a property for the student's GPA.

19
Method: public void PrintStudentDetails() prints the student's details. It calls base.PrintDetails() to
print the Name and Age inherited from Person, then prints the StudentId and GPA.

- Output:

Figure 7: Output Inheritance.

c. Polymorphism:

- Input:

static void Main(string[] args)


{
Person person1 = new Student();
person1.Name = "John Doe";
((Student)person1).StudentId = "123456";
person1.PrintDetails();
Person person2 = new Teacher();
person2.Name = "Jane Smith";
((Teacher)person2).EmployeeId = "7890";
person2.PrintDetails();
Console.ReadLine();
}
public abstract class Person
{
public string Name { get; set; }
public virtual void PrintDetails()
{
Console.WriteLine($"Name: {Name}");
}
}

20
public class Student : Person
{
public string StudentId { get; set; }
public override void PrintDetails()
{
base.PrintDetails();
Console.WriteLine($"Student ID: {StudentId}");
}
}
public class Teacher : Person
{
public string EmployeeId { get; set; }
public override void PrintDetails()
{
base.PrintDetails();
Console.WriteLine($"Employee ID: {EmployeeId}");
}
}

- Explains:

Creating and Using a Student Object: Person person1 = new Student(); creates a new Student object,
but the reference is of type Person. person1.Name = "John Doe"; sets the Name property inherited
from Person. ((Student)person1).StudentId = "123456"; casts person1 to Student and sets the
StudentId property. person1.PrintDetails(); calls the PrintDetails method, which is overridden in
Student to print the name and student ID.

Creating and Using a Teacher Object: Person person2 = new Teacher(); creates a new Teacher object,
but the reference is of type Person. person2.Name = "Jane Smith"; sets the Name property inherited
from Person. ((Teacher)person2).EmployeeId = "7890"; casts person2 to Teacher and sets the
EmployeeId property. person2.PrintDetails(); calls the PrintDetails method, which is overridden in
Teacher to print the name and employee ID.

Keeping Console Open: Console.ReadLine(); waits for the user to press Enter before closing the console
window.

Abstract Class: public abstract class Person defines Person as an abstract class, meaning it cannot be
instantiated directly.

21
Properties: public string Name { get; set; set; } defines a property for the person's name.

Virtual Method: public virtual void PrintDetails() is a virtual method that prints the name. This method
can be overridden in derived classes.

Inheritance: public class Student : Person declares that Student inherits from Person.

Additional Property: public string StudentId { get; set; set; } defines a property for the student ID.

Overriding Method: public override void PrintDetails() overrides the PrintDetails method to include
printing the student ID along with the name.

Inheritance: public class Teacher : Person declares that Teacher inherits from Person.

Additional Property: public string EmployeeId { get; set; set; } defines a property for the employee ID.

Overriding Method: public override void PrintDetails() overrides the PrintDetails method to include
printing the employee ID along with the name.

- Output:

Figure 8: Output Polymorphism.

d. Abstraction:

- Input:

static void Main(string[] args)


{
Student student = new Student();
student.Name = "John";

22
student.Age = 20;
student.GPA = 3.5;
student.PrintDetails();
Console.Read();
}
public abstract class Person
{
public string Name { get; set; }
public int Age { get; set; }
// Abstract method
public abstract void PrintDetails();
}
// Concrete class inheriting from the abstract base class
public class Student : Person
{
public double GPA { get; set; }

public override void PrintDetails()


{
Console.WriteLine($"Name: {Name}");
Console.WriteLine($"Age: {Age}");
Console.WriteLine($"GPA: {GPA}");
}
}

- Explains:

Creating a Student Object: Student student = new Student(); creates a new instance of the Student
class.

Setting Properties: student.Name = "John"; sets the Name property inherited from the Person class.
student.Age = 20; sets the Age property inherited from the Person class. student.GPA = 3.5; sets the
GPA property specific to the Student class.

Printing Details: student.PrintDetails(); calls the overridden PrintDetails method to print the student's
details.

Keeping Console Open: Console.Read(); waits for the user to press a key before closing the console
window.

23
Abstract Class: public abstract class Person defines Person as an abstract class, meaning it cannot be
instantiated directly.

Properties: public string Name { get; set; set; } defines a property for the person's name. public int Age
{ get; set; set; } defines a property for the person's age.

Abstract Method: public abstract void PrintDetails(); is an abstract method that must be implemented
by any derived class.

Inheritance: public class Student : Person declares that Student inherits from Person.

Additional Property: public double GPA { get; set; set; } defines a property for the student's GPA.

Overriding Method: public override void PrintDetails() provides the implementation for the abstract
PrintDetails method, printing the Name, Age, and GPA.

- Output:

Figure 9: Output Abstraction.

2.3. Class Relationships:

In OOP, class relationships describe how different classes interact with each other. These relationships
are essential for designing robust and maintainable software. The main types of class relationships are:

Association: A general relationship between classes in which one class uses or interacts with another.

24
Aggregation: A special form of association that represents a “whole-part” relationship, in which the
part can exist independently of the whole.

Composition: A stronger form of aggregation in which the part cannot exist without the whole.

2.3.1. Composition:

Composition is a "partial" relationship. Composition simply means using instance variables that refer to
other objects. In the layout, both entities are dependent on each other.

Figure 10: Filled Diamond Arrow.

Composition is a relationship in which one object is made up of other objects. Container objects
contain component objects and manage their lifecycles. A composition relationship is often expressed
by having an object that is a member of another class.

- Advantages:

Strong Ownership: Explicitly define strong ownership where contained objects do not exist without the
parent.

Encapsulation: Promotes the encapsulation process by ensuring contained objects are tightly coupled
to their parents.

- Disadvantages:

Inflexibility: Changes in the parent object often require changes in the composite object.

Lifecycle management: The parent object must manage the lifecycle of all composite objects, which
can be complicated.

25
- Example:

Build a digital contact book application. The contact book is the whole, each contact entry is a part.
Each contact entry is fully owned and managed by the contact book. If a contact book is deleted or
destroyed, all related contact entries are also deleted.

Figure 11: Composition Class Relationships.

 Explain:

- ContactBook:

Properties: contacts: A list of Contact objects.

Method: addContact(contact: Contact): void: Method to add a Contact object to the contacts list.
displayContacts(): void: Method to display all contacts in the contacts list.

- Contact:

Properties:

name: A character string representing the contact's name.

phoneNumber: A character string representing the contact's phone number.

- Relationship:

There is a composition relationship (denoted by the filled diamond) between ContactBook and
Contact. This indicates that ContactBook contains and manages the lifecycle of Contact objects. The
Contact objects do not exist independently of the ContactBook.

26
2.3.2. Association:

Association is a “has-a” type relationship. Association establishes a relationship between two classes by
passing their objects. Association relationships can be one to one, One to many, many to one, and
many to many.

Figure 12: Simple Line.

Associations help implement relationships to illustrate different types of associations and how they can
be used in modeling real-world problems. This relationship takes place when objects of one class are
known to be objects of another class. Furthermore, objects can be created or deleted independently.

- Advantages:

Flexibility: Objects can be associated dynamically at runtime, allowing for flexible design.

Reusability: Classes involved in associations can be reused in different contexts without modification.
Decoupling: Reduces dependency between classes, promoting a more modular design.

- Disadvantages:

Complexity: Managing associations can add complexity, especially with bidirectional associations.

Maintenance: Keeping track of associated objects and ensuring consistency can be challenging.

- Example:

A teacher and a student. A teacher can teach multiple students and a student can be taught by
multiple teachers. Both have their own lifecycle and none owns the other.

27
Figure 13: Association Class Relationships.

 Explain:

- Teacher:

Properties:

name: A character string representing the teacher's name.

students: A list of Student objects that the teacher teaches.

Method:

Teacher(name: String): Constructor to create a new Teacher object with the provided name.

addStudent(student: Student): void: Method to add a Student object to the students list.

getStudents(): List<Student>: Method that returns a list of students.

teach(): void: Method representing the teacher's teaching action.

- Student:

Properties:

name: A character string representing the student's name.

teachers: A list of Teacher objects that the student studies.

Method:

Student(name: String): Constructor to create a new Student object with the provided name.

28
addTeacher(teacher: Teacher): void: Method to add a Teacher object to the list of teachers.

getTeachers(): List<Teacher>: Method that returns a list of teachers.

study(): void: Method representing the student's learning action.

- Relationship:

The relationship between Teacher and Student is a many-to-many relationship. One teacher can teach
many students and one student can learn from many teachers.

On the diagram, this relationship is shown by each class having a list of objects of the other class
(students in Teacher and teachers in Student).

2.3.3. Aggregation:

Aggregation is based on the "has-a" relationship. Aggregation is a special form of association. In


association, there is not any class (entity) as the owner but in aggregation, an entity acts as the owner.
Taken together, both entities meet to do some work and then separate.

Figure 14: Empty Diamond Arrow.

Aggregation is also a part-whole relationship, in which one class contains another class that is a part. Its
role in modeling the relationship between classes is a "has-a" relationship and is a one-way association.
This relationship exists when one class owns but shares references to another class's objects.

29
- Advantages:

Clear Ownership: Clearly defines a relationship where one object "contains" others but they can exist
independently.

Reusability: Aggregated objects can be reused elsewhere.

Modularity: Aggregated objects can be developed and tested independently.

- Disadvantages:

Complex Lifecycles: Managing the lifecycle of aggregated objects can be complex, especially when the
parent object is destroyed.

Dependency Management: Changes in the parent can affect the aggregated objects, requiring careful
management.

- Example:

The company can be considered as a whole, and employees as a part. Employees belong to the
company and a company can have many employees. However, if the company no longer exists, the
employee can still exist independently.

Figure 15: Aggregation Class Relationships.

30
 Explain:

- Company:

Attributes:

name: A string representing the name of the company.

employees: A list of Employee objects representing the employees of the company.

Methods:

company(name: String): Constructor that initializes the company with a name.

getName(): String: Method that returns the name of the company.

addEmployee(employee: Employee): void: Method to add an employee to the company's list of


employees.

getEmployees(): List<Employee>: Method that returns the list of employees in the company.

- Employee:

Attributes:

name: A string representing the name of the employee.

Methods:

Employee(name: String): Constructor that initializes the employee with a name.

getName(): String: Method that returns the name of the employee.

- Relationship:

The diamond shape connecting Company and Employee indicates a composition relationship. This
means that a Company is composed of Employee objects, and the employees are a part of the
company. If the company ceases to exist, its employees are also removed (at least in the context of this
diagram).

31
Comparison of class relationships:

Character Composition Association Aggreation

Definition General relationship Special form of Strong form of


where one class uses association aggregation where
or interacts with representing a "whole- parts cannot exist
another. part" relationship independently of the
where parts can exist whole.
independently.

Existence Dependency Parts can exist Parts can exist Parts cannot exist
independently of the independently of the independently of the
whole. whole. whole.

Type of Relationship "uses-a" or "knows-a" "has-a" "contains-a"

Lifetime Management Independent lifetimes; Parts can live Dependent lifetimes; if


objects can live independently; the the whole is deleted,
separately. whole can be deleted the parts are also
without affecting the deleted.
parts.

Example in Real World ContactBook and Teacher and Student. Company and
Contact. Employee

2.4. SOLID principle:


2.4.1. What is SOLID principle ?

If we talk about studying the concept of object orientation as well as its class relationship, it is also
essential to introduce some solid principles as well as its importance. In this section, I will give their
importance in software design, and I will also give some SOLID principles (SRP, OCP, LSP, ISP, DIP).

32
First, we must understand what is the concept of the Snake principle? The Snake Principle is a
programming principle used to guide code design in object-oriented programming (OOP). This principle
is named after software developer Robert C. Martin, who is also known as "Uncle Bob". It is also part of
a set of principles called SOLID, which represents flexible and maintainable software design principles.

The SOLID principle consists of 5 main principles:

- Single Responsibility Principle – SRP

- Open/Closed Principle – OCP

- Liskov Substitution Principle – LSP

- Interface Segregation Principle – ISP

- Dependency Inversion Principle – DIP

Figure 16: SOLID principle.

2.4.2. SRP ( Single Responsibility Principle ):

- Definition: The SRP principle holds that a class should have only one reason to change, i.e., it should
have only one responsibility or a single function.

33
Figure 17: SRP ( Single Responsibility Principle ).

- Advantages:

Reduce layer complexity.

Increase the reusability of source code.

Increased maintainability and easy error correction.

- Disadvantages:

This can lead to the creation of more layers, complicating the structure of the system.

It takes a lot of time and effort to design and maintain single-task classes.

2.4.3. OCP ( Open/Closed Principle ):

- Definition: The OCP principle holds that software entities (classes, modules, functions, etc.) should be
open for expansion but closed for modification. That is, you should be able to extend their functionality
without having to change the existing source code.

34
Figure 18: OCP ( Open/Closed Principle ).

- Advantages:

Increase the scalability of the system without compromising the current source code.

Reduce the risk of errors when changing software.

- Disadvantages:

This can lead to overly complex designs and unnecessary abstractions.

Difficulty in anticipating all potential expansion scenarios.

2.4.4. LSP ( Liskov Substitution Principle ):

- Definition: The LSP principle states that child classes must be able to replace the parent class without
changing the correctness of the program. That is, the child class must maintain the behavior of the
father class.

Figure 19: LSP ( Liskov Substitution Principle ).

- Advantages:

35
Ensure the consistency and correctness of the program when using polymorphisms.

Increase the reusability and extensibility of the source code.

- Disadvantages:

Flexibility in subclass design may be limited.

It requires a deep understanding of the relationship between the father and the child class.

2.4.5. ISP ( Interface Segregation Principle ):

- Definition: The ISP principle states that a class should not be forced to depend on interfaces that it
does not use. Instead, it is recommended to separate large interfaces into many smaller, more specific
interfaces.

Figure 20: ISP ( Interface Segregation Principle ).

- Advantage:

Reduce unnecessary dependencies between layers.

Increase flexibility and easily change the interface without affecting other layers.

- Disadvantages:

This can lead to the creation of many small interfaces, complicating the system.

Requires careful management and organization of the interface.

36
2.4.6. DIP ( Dependency Inversion Principle ):

- Definition: The DIP principle holds that high-level modules should not depend on low-level modules;
both should depend on abstract interfaces. At the same time, abstract interfaces should not depend on
details; details should depend on abstract interfaces.

Figure 21: DIP ( Dependency Inversion Principle ).

- Advantages:

Increase the modularity and scalability of the system.

Reduce specific dependencies between modules, easy replacement and maintenance.

- Disadvantages:

It can lead to complex and confusing designs.

Requires skills and a deep understanding of object-oriented design.

2.4.7. The importance of SOLID principle in software design:


SOLID principles have always provided a set of guidelines and best practices for designing software that
is maintainable, flexible, and robust. However, it is also of significant importance in software design for
several reasons:

37
- Maintainability: By following SOLID principles, you can create code that is easier to understand,
modify, and maintain. Aims to promote modular and decoupled code, making it simpler to make
changes without affecting the entire system.

- Flexibility: SOLID principles encourage designs that are flexible and adaptable to change. This reduces
the risk of errors and makes the system more scalable.

- Testability: SOLID principles contribute to improving the testability of software. The Single
Responsibility Principle (SRP) ensures that each class has a single, clearly defined responsibility, making
it easier to write focused and comprehensive unit tests.

- Reusability: SOLID principles encourage the creation of reusable code components. This also increases
the chances of reusing them in different contexts or projects, leading to more efficient development
and reduced duplication of effort.

- Collaboration: Following SOLID principles will enhance collaboration among developers within a team.
Consistent application of SOLID principles improves code readability and makes it easier for multiple
developers to work on the same code base or collaborate on different parts of a larger system.

- Overall quality: Applying SOLID principles results in higher quality software. By creating well-
structured and modular code, it leads to fewer problems, faster development cycles, and more stable
and reliable software products.

III. Clean technique and data structure:


After applying and presenting the structure and design of a software system. This increases modularity,
improves maintainability and scalability, and provides certainty in system management. Next, I will
explain how explicit encoding techniques can impact the use of data structures and operations when
writing algorithms. This increases the clarity, readability, reuse, ease of testing and debugging, and
scalability and flexibility of the system.

38
3.1. Clean Coding Techniques:
3.1.1. What is clean coding ?

Clean coding techniques are practices and principles that focus on writing code that is easy to read,
understand, and maintain. These techniques ensure the security and safety of data during storage and
transmission. The main goal of clean encryption techniques is to ensure secure, maintainable, and
efficient encryption implementations.

Clean encryption techniques include using strong and proven encryption algorithms such as AES, RSA,
and ECC, and securely managing keys. Clean coding also requires writing code that is easy to read and
understand, using meaningful variable, function, and class names, and separating the coding logic into
small, reusable modules. Additionally, clean encryption techniques must comply with regulations and
standards, must maintain consistency in code naming and formatting, and design the coding system to
be scalable and integrate easily with other technologies. other system.

Figure 22: Clean Coding Techniques.

39
Research on clean coding techniques enhances the accuracy, understanding and application of
chemistry, saves time and resources, and promotes collaboration and knowledge sharing within the
chemistry research community.

To better understand the research and practice of clean encryption techniques, I will give an example
from a student information system management project.

- Example: Student Information System Management.

3.1.2. Naming:

Proper naming is crucial to clean coding. Names should be descriptive and communicate the purpose
of a variable, function, or class. Proper naming helps others (and your future self) understand your
code quickly.

Example:

public class Student


{
private String name;
private int age;
private List<String> courses;

public void setName(String studentName)


{
this.name = studentName;
}

public String getName()


{
return this.name;
}

40
public void addCourse(String course)
{
courses.add(course);
}

public void printDetails()


{
System.out.println("Name: " + name);
System.out.println("Age: " + age);
System.out.println("Courses: " + String.join(", ", courses));
}
}

Explanation:

private String name: Stores the student's name. It is private, meaning it can only be accessed directly
within the Student class.

private int age: Stores the student's age. It is also private.

private List<String> courses: A list that holds the names of courses the student is enrolled in. It is
private, so it cannot be accessed directly from outside the class.

public void setName(String studentName): Sets the student's name. It takes a String parameter
(studentName) and assigns it to the name field.

public String getName(): Returns the student's name. It returns the value of the name field.

public void addCourse(String course): Adds a course to the courses list. It takes a String parameter
(course) and adds it to the courses list. Note that there is an issue here: the courses list is not
initialized, which will cause a NullPointerException when trying to add a course.

public void printDetails(): Prints the details of the student to the console. It prints the student's name,
age, and a comma-separated list of courses.

41
3.1.3. Modularity:

Modularity involves breaking down a program into smaller, manageable, and reusable pieces
(modules). Each module should have a single responsibility and should be loosely coupled with other
modules.

Example:

public class StudentManager


{
public void manageStudent(String name, int age, List<String> courses)
{
Student student = createStudent(name, age, courses);
printStudentDetails(student);
}
private Student createStudent(String name, int age, List<String> courses)
{
Student student = new Student();
student.setName(name);
student.setAge(age);
student.setCourses(courses);
return student;
}
private void printStudentDetails(Student student)
{
student.printDetails();
}
}

Explanation:

manageStudent(String name, int age, List<String> courses) method:

This method takes information about the student including name, age, and list of courses.

Then, it creates a student object by calling createStudent(name, age, courses) method.

Next, it prints out the student details by calling printStudentDetails(student) method.

createStudent(String name, int age, List<String> courses) method:

42
This method creates and returns a new Student object.

First, it instantiates a Student object.

Then, it calls setName(name), setAge(age), and setCourses(courses) methods on the student object to
set the student information.

Finally, it returns the created student object.

printStudentDetails(Student student) Method:

This method prints the details of a student object by calling the printDetails() method of the Student
class.

3.1.4. Comments:

Comments should be used to explain why code exists, rather than what the code is doing. If the code is
clear and well-named, comments should be minimal.

Example:

public class Student


{
private String name;
private int age;
private List<String> courses;

// Sets the student's name


public void setName(String studentName)
{
this.name = studentName;
}

// Prints student's details to the console


public void printDetails()
{
System.out.println("Name: " + name);
System.out.println("Age: " + age);
System.out.println("Courses: " + String.join(", ", courses));
}

43
}

Explain:

Constructor: There is no explicit constructor defined in the code. Java provides a default constructor if
no other constructor is defined explicitly.

setName() method: This method is a setter method that sets the name of the student. It takes a String
parameter studentName and assigns it to the name instance variable of the Student object.

printDetails() method: This method is used to print the details of the student to the console. It prints
out the student's name, age, and courses to the console. However, there is a potential issue in this
method:

The age variable is declared but not initialized. It will have the default value 0 for an integer type.

The courses variable is a List<String> but is not initialized in the class. If it's not initialized elsewhere in
the code, trying to call printDetails() without adding any courses to the courses list will result in a
NullPointerException.

3.1.5. Consistency:

Consistency in coding style helps maintain readability and uniformity across the codebase. This
includes consistent naming conventions, indentation, spacing, and code structure.

Example:

public class StudentManager


{
public void manageStudent(String studentName, int studentAge, List<String> studentCourses)
{
Student student = createStudent(studentName, studentAge, studentCourses);
printStudentDetails(student);
}

private Student createStudent(String name, int age, List<String> courses)

44
{
Student student = new Student();
student.setName(name);
student.setAge(age);
student.setCourses(courses);
return student;
}

private void printStudentDetails(Student student)


{
student.printDetails();
}
}

Explain:

manageStudent(String studentName, int studentAge, List<String> studentCourses) method:

This method takes information about the student including name (studentName), age (studentAge),
and list of courses (studentCourses).

Next, it creates a student object by calling createStudent(studentName, studentAge, studentCourses)


method.

Then, it prints out the student details by calling printStudentDetails(student) method.

createStudent(String name, int age, List<String> courses) method:

This method still creates and returns a new Student object as before.

It instantiates a Student object, sets the student's name, age, and courses, and finally returns the
student object.

printStudentDetails(Student student) method:

This method still prints the details of a student object by calling the printDetails() method of the
Student class.

45
3.2. Impact on Data Structures and Operations:

Above, I have given clean coding techniques explicitly while applying clean chemistry techniques such
as meaningful naming, modularity, comments, and consistency. On the other hand, the impact on the
structure and data operations in the system will be very significant. In this section, I will lay out the
important foundations that impact data structure and operations. At the same time, I will also provide
examples and explain how explicit coding techniques on Data Structures and Operations work.

Here's the impact on data structure and activity:

Clear and understandable data structure: When variables, classes, and methods are given meaningful
names, the data structure becomes easier to read and understand. This helps to quickly understand
the data structure and its components.

Modularity and reuse: Dividing the system into small and independent modules helps increase
modularity. This also results in the data structure being logically separated and easier to manage.

Commenting and documenting data: Adding complete and clear comments to each piece of code and
module not only helps programmers better understand the purpose and logic of the data.

Data consistency: Consistent naming and data structure helps avoid inconsistencies and confusion
during development and maintenance. This ensures that the data is used properly and gives accurate
results.

Efficient and easy to maintain: Thanks to its clear data structure and modularity, system maintenance
and expansion become easier, and system functionality can be expanded without seriously affecting
the system. pay attention to other parts.

To better understand the impact on data structure and operations, below I will provide examples and
explain how explicit encryption techniques work on Data Structure and Operations.

Example: Manage student information system.

1. Data Structures:

46
Example: Student Class.

- Consider a ‘Student’ class in the SIS system:

public class Student {

private int studentId;

private String name;

private int age;

private String email;

Explicit Encoding Technique: Use meaningful variable names (‘studentId’, ‘name’, ‘age’, ‘email’) to
clearly represent attributes of a student. This enhances readability and understanding of the data
structure.

2. Operations Structures:

Example: Adding Students

- Implementing a method to add students to the SIMS:

public class StudentManager {

private List<Student> studentList;

public StudentManager() {

studentList = new ArrayList<>();

public void addStudent(Student student) {

studentList.add(student);

47
Explicit Encoding Technique: The ‘addStudent’ method explicitly adds a ‘Student’ object to the
‘studentList’. This operation is clearly defined and encapsulated within the ‘StudentManager’ class,
promoting modularity and reusability.

3. Encoding Data Integrity:

Example: Validating Student Data

- Ensuring student data integrity during operations:

public class StudentManager


{

public boolean validateStudentData(Student student)


{

if (student.getName() == null || student.getName().isEmpty())


{
System.out.println("Error: Student name cannot be empty."); return false;
}

if (student.getAge() <= 0)
{
System.out.println("Error: Invalid student age."); return false;
}

return true;

Explicit Encoding Technique: The ‘validateStudentData’ method checks and ensures that essential data
fields (‘name’, ‘age’, etc.) adhere to predefined rules. This promotes data consistency and reliability
across operations.

4. Data Operations and Maintenance:

Example: Updating Student Information

- Implementing a method to update student information:

48
public class StudentManager
{

public void updateStudentInformation(int studentId, String newName, int newAge, String newEmail)
{
for (Student student : studentList)
{
if (student.getStudentId() == studentId)
{
student.setName(newName); student.setAge(newAge); student.setEmail(newEmail);
System.out.println("Student information updated successfully."); return;
}

System.out.println("Error: Student not found.");

Explicit Encoding Technique: The ‘updateStudentInformation’ method explicitly modifies student


information based on specified parameters (‘studentId’, ‘newName’, ‘newAge’, ‘newEmail’). This
ensures that updates are precise and targeted, minimizing errors and maintaining data accuracy.

49
IV. Design pattern in practice:

After I apply and present the structure and design of a software system. This has brought certainty in
system management. Additionally, I've also explained how explicit coding techniques can impact the use
of data structures and operations when writing algorithms. This has increased the clarity, readability and
flexibility of the system. In the next section, I will design the application's architecture and a suitable
testing mode for SIMS. More importantly, my team realized that SIMS data is a large data set. The team
also decided to deploy the application using ASP .NET Core. Here, I will use important diagrams like Use
Case Diagram, Class Diagram, and Package Diagram. With that, I'll explain how to apply SOLID principles
in your team design. Also make sure your design uses SOLID principles.

4.1. Overview ASP .NET Core:

ASP.NET Core is a modern, high-performance web development framework for .NET, running on
Windows, Linux, macOS, and Docker. It is a free, open source, and cross-platform framework for building
cloud-based applications, such as web apps, IoT apps, and mobile backends. It is designed to run in the
cloud as well as on-premises.

ASP.NET Core is the open source version of ASP.NET, running on macOS, Linux and Windows. ASP.NET
Core was first released in 2016 and is a redesign of previous Windows-only versions of ASP.NET.

ASP.NET Core offers many different support lifecycle options to meet your application needs. You can
choose a long-term support release or run with the latest release if you commit to upgrading more
frequently. See our support policy for more details.

50
Figure 23: ASP .NET Core.

4.2. A use case diagram:

A use case diagram is a visual representation in the Unified Modeling Language (UML) that depicts the
interactions between actors (users or external systems) and a system. It provides a high-level overview of
the functionality and behavior of the system from the perspective of the actors.

Below is a use case diagram in the SIMS project:

51
Figure 24: A use case diagram.

Explain:

Through the image above, we can see that this use case diagram shows how the SIMS system works and
interacts. Use Case Diagram for SIMS system includes three main user groups: Admin, Teacher, and
Student. Admins can log in to the system to perform important functions such as uploading CSV files,
viewing and editing student information, and deleting student data when necessary. Teachers can also
log in to view student information and create reports. Finally, Students can also log in to view personal
information. Each user group has access to corresponding functions, and Use Case Diagram clearly shows
the relationship and authority between these groups in the system. This diagram provides an easy-to-
understand overview of the main features of the SIMS system and how users interact with it.

4.3. A class diagram:

A class diagram is a type of UML (Unified Modeling Language) diagram that represents the structure and
relationships of classes in a system. It provides a visual representation of the classes, their attributes,
operations (methods), and the associations between them.

Below is a class diagram in the SIMS project:

52
Figure 25: A class diagram.

Explain:

User and Subclasses: User is the superclass of Admin, Teacher, and Student. All of these subclasses
inherit properties and methods from User.

Admin and CSVProcessor: Admin uses CSVProcessor to process CSV files. The ProcessFile method in
CSVProcessor returns a list of StudentData.

Student and StudentData: Student owns many StudentData objects, which reflect student details.

4.4. A package diagram:

A package diagram is a type of UML (Unified Modeling Language) diagram that represents the
organization and structure of packages in a system or software application. It provides a high-level view
of the system's components and the relationships between them.

Below is a package diagram in the SIMS project:

Figure 26: A package diagram.

53
Explain:

Model: Defines core entities such as Users, Students, Teachers, Administrators, Courses, and Reports.
This represents the core data structure with specific properties and behaviors.

Controller: Manage user interactions through StudentController, TeacherController, AdminController


and CourseController. Be responsible for handling user interactions

Views: Represents the user interface (StudentView, TeacherView, AdminView, CourseView). Provides a
user interface to interact with various aspects of the system

Service: Implement business logic (StudentService, TeacherService, AdminService, CourseService). It will


be responsible for handling and coordinating operations on entities from the controller.

Repository: Handles data retention (Student Repository, Teacher Repository, Administrative Repository,
Course Repository). This will help in retrieving data to their respective entities, ensuring separation of
data access concerns.

4.5. An explanation of how SOLID principles have been applied in

your team design:

During the design of the student information management system (SIMS) project, our team
systematically applied SOLID principles to ensure system flexibility, maintainability, and scalability.

First, we adhere to the Single Responsibility Principle (SRP) by designing each class with a single
responsibility, for example, the User class only handles authentication and user authorization (Login),
while The CSV Processor class only focuses on CSV file processing.

Second, there is the Open/Closed Principle (OCP) applied through the use of interfaces and abstract
classes, allowing functionality to be extended without modifying existing code. For example, the IService
interface is defined so that service classes such as StudentService and CSVService can deploy and extend
functionality flexibly.

54
Third, it is impossible not to mention the Liskov Substitution Principle (LSP) which is guaranteed by
ensuring that subclasses (such as Admin, Teacher, Student) can replace the base class (User) without
affecting system correctness. This promotes polymorphism and helps maintain consistency in the source
code. Additionally, the Interface Slicing Principle (ISP) is applied by defining separate interfaces tailored
to each customer's specific requirements.

Finally, the Dependency Inversion Principle (DIP) was implemented through the use of dependency
injection (DI) to invert dependencies between modules. This reduces constraints and increases flexibility
in testing and maintaining the code. Thereby, we applied SOLID principles in our team's design which
brought important benefits to this project. It not only improves the quality of the source code but also
promotes efficient and collaborative development.

V. Apply SOLID principle in SIMS application:


5.1. Creational design patterns are used in practices:
5.1.1. What is Creational DP:

Creational design patterns are a category of design patterns in software engineering that deal with object
creation mechanisms. They abstract the instantiation process, making a system independent of how its
objects are created, composed, and represented. These patterns help make a design more flexible in
terms of what gets created, who creates it, how it gets created, and when it gets created.

Creational design patterns abstract the instantiation process. They help make a system independent of
how its objects are created, composed, and represented. A class creational pattern uses inheritance to
vary the class that’s instantiated, whereas an object creational pattern will delegate instantiation to
another object.

Creational patterns give a lot of flexibility in what gets created, who creates it, how it gets created, and,
when.

There are two recurring themes in these patterns:

55
- They all encapsulate knowledge about which concrete class the system uses.

- They hide how instances of these classes are created and put together.

Figure 27: Creational design patterns.

5.1.2. Apply in my project:

In our SIMS implementation, we have applied the following creational design patterns. These creational
design patterns are related to how objects are created. They abstract the instantiation process, making it
more flexible and adaptable. In practice, these patterns are often used to increase flexibility and reuse of
existing code. Some common creational design patterns include Singleton, Factory Method, and Builder:

- Singleton Pattern: The Singleton pattern ensures that a class has only one instance and provides a
global access point to it. This is especially useful for our DatabaseConnection class in SIMS, where we
need a single, consistent connection to the database to effectively manage student data. This pattern
prevents problems associated with multiple database connections, ensuring efficient resource usage and
consistent data access.

- Factory Method pattern: This pattern is used to create objects without specifying the exact class of the
object to be created. In our SIMS, Factory Method can be used to create different types of users (Admin,
Teacher, Student). This ensures that the system can instantiate role-based user objects dynamically,

56
adhering to the Single Responsibility Principle (SRP) by delegating generation logic to a separate factory
class.

- The Builder pattern: is useful for constructing complex objects step by step. In SIMS, this pattern can be
applied to create instances of complex objects such as `StudentProfile` that may have multiple optional
fields (e.g., contact information, course details, grades). The Builder pattern provides a flexible solution
for object construction, enhancing readability and maintainability by separating the construction and
representation of objects.

The application of innovative design patterns in the SIMS project significantly improved the flexibility,
maintainability, and resource management of the system. By abstracting the object creation process,
these patterns enabled dynamic object instantiation, efficient resource usage, and clear separation of
concerns, resulting in a more robust and adaptive student information management system.

5.2. Structural design patterns are used in practices:


5.2.1. What is Structural DP:

In software design, Structural Design Patterns (Structural DP) are patterns that simplify the structure of a
software system by defining simple ways to implement relationships between entities. These patterns
are designed to help you build flexible and reusable software.

They focus on how classes and objects are combined to form larger structures. Structural design patterns
ensure that if one part of the system changes, the entire structure does not need to change.

There are two recurring themes in these patterns:

This pattern is particularly useful for creating independently developed class libraries that work together.

Structural design patterns describe ways to combine objects to implement new functionality. The added
flexibility of object composition comes from the ability to change the composition at runtime, which is
not possible with static class composition.

57
Figure 28: Structural Design Patterns.

5.2.2. Apply in my project:

Next, to be able to successfully apply it to the SIMS project, we applied structural design patterns.
Structural design is something that cannot be ignored. Because structural design patterns deal with
object composition and often define simple ways to realize relationships between entities. Some
common structural design patterns include Adapter, Decorator, and Composite.

- Adapter Pattern: The Adapter pattern allows incompatible interfaces to work together. In SIMS,
Adapter can be used to integrate legacy systems or external APIs to manage student data. For example,
if the current university system uses a different format for student data, the Adapter can convert this
data into a format compatible with our system.

- Composite Pattern: The Composite pattern is used to handle individual objects and their components
in a unified way. In our system, this can be applied to manage student groups. For example, a class can
be represented as an aggregate of students, allowing operations to be performed consistently across
both individual students and groups (classes).

- Decorator Pattern: It allows adding behavior to each object dynamically without affecting the behavior
of other objects in the same class. In our SIMS, we can use this pattern to add additional functionality to

58
user notifications. For example, the basic notification functionality can be extended to include email
notifications, SMS notifications, and push notifications using decorator images.

The application of structural design patterns in the SIMS project has significantly improved the system's
ability to manage relationships between entities, integrate with external systems, and dynamically
extend functionalities. These patterns have ensured that the system remains flexible, maintainable, and
scalable, capable of adapting to new requirements and technologies with minimal disruption to existing
code.

5.3. Behavioural design patterns are used in practices:


5.3.1. What is Behavioural DP:

Behavioral design patterns are concerned with algorithms and the assignment of responsibilities
between objects. Behavioral patterns describe not only object or class patterns but also communication
patterns between them. These patterns represent complex control flows that are difficult to follow at
runtime.

In these behavioral design patterns, the interactions between objects must be in such a way that they
can easily communicate with each other and still be loosely coupled. This means that the
implementation and the client must be loosely coupled to avoid hard coding and dependencies.

There are three recurring themes in these patterns:

- Behavioral class patterns use inheritance to distribute behavior between classes.

- Behavioral object patterns use object composition instead of inheritance.

- Behavioral object patterns involve encapsulating behavior in an object and distributing requirements to
that object.

59
Figure 29: Behavioural design patterns.

5.3.2. Apply in my project:

Finally, Behavioral design patterns play an equally important role. Because Behavioral design patterns
focus on communication between objects, encapsulating processes and interactions. Some popular
behavioral design patterns include Strategy, Observer, and Command.

- Observer Pattern: The Observer Pattern defines one-to-many dependencies between objects so that
when one object changes state, all of its dependent objects are notified and automatically updated. In
our system, this can be used to notify students and teachers of schedules or grade updates. For example,
when an administrator updates a student's grade, all observers (students and teachers) are notified of
the change.

- Strategy Pattern: The Strategy Pattern defines a group of algorithms, encapsulates each algorithm, and
makes them interchangeable. It allows the algorithm to change independently of the clients that use it.
In SIMS, different grading strategies can be encapsulated using this pattern. For example, we can have
different algorithms for grading based on assignments, tests, or projects. These algorithms can be
selected and applied at runtime based on the course requirements.

60
- Command pattern: allows encapsulation of requests into independent objects, allows request handling,
undoing, and logging. It separates the request sender and the executor, and allows for extensibility and
customization of actions.

The application of behavioral design patterns in the SIMS project has significantly enhanced the system's
communication and interaction capabilities. These patterns have provided flexible, maintainable, and
dynamic solutions for managing interactions, algorithms, and user actions, ensuring that the system can
efficiently handle various processes and adapt to changing requirements.

Through this we can see that applying and designing design patterns not only helps improve the
structure and performance of the software, but also provides flexibility and ease of maintenance. It
brings many benefits to the system, while also providing specific requirements for the SIMS project.
Using the right design patterns can help increase modularity, reduce dependencies, and create highly
scalable and reusable software systems. By using these design patterns, our team can improve the
modularity, scalability, and maintainability of SIMS, creating an efficient and flexible system.

VI. Analyse the SIMS application and evaluate how


adhering to SOLID principles has influenced the
design and development:
6.1. Analyse the SIMS application:

During the adoption and design process, our team came up with design patterns that created objects,
structures, and behaviors. And it plays a key role in creating robust and maintainable systems.
Generative, structural, and behavioral design patterns are fundamental categories that provide solutions
to various aspects of software design. Below is a breakdown of how these design patterns are used in
practice or in our team's proposed solution. Applying design patterns to projects is essential, because
they bring many personal benefits.

61
So first, we have to mention the Creative Design Pattern. Creative design patterns relate to how objects
are created. They abstract the initialization process, making it more flexible and adaptable. In practice,
these patterns are often used to increase flexibility and reuse existing code. Some popular creational
design patterns include Singleton, Factory Method, and Builder:

- Singleton Pattern: The Singleton pattern ensures that a class has only one instance and provides a
global access point to it. This is especially useful for our DatabaseConnection class in SIMS, where we
need a single, consistent connection to the database to effectively manage student data. This pattern
prevents problems associated with multiple database connections, ensuring efficient resource usage and
consistent data access.

- Factory Method pattern: This pattern is used to create objects without specifying the exact class of the
object to be created. In our SIMS, Factory Method can be used to create different types of users ( Admin,
Teacher, Student). This ensures that the system can instantiate role-based user objects dynamically,
adhering to the Single Responsibility Principle (SRP) by delegating generation logic to a separate factory
class.

- The Builder pattern: is useful for constructing complex objects step by step. In SIMS, this pattern can be
applied to create instances of complex objects such as `StudentProfile` that may have multiple optional
fields (e.g., contact information, course details, grades). The Builder pattern provides a flexible solution
for object construction, enhancing readability and maintainability by separating the construction and
representation of objects.

Second, the structural design is something that cannot be ignored. Because Structural design patterns
deal with object composition and often define simple ways to realize relationships between entities.
Some popular structural design models include Adapter, Decorator and Composite.

- Adapter Pattern: The Adapter pattern allows incompatible interfaces to work together. In SIMS,
Adapters can be used to integrate legacy systems or external APIs to manage student data. For example,
if the current university system uses a different format for student data, the Adapter can convert this
data into a format compatible with our system.

62
- Composite Pattern: The Composite pattern is used to handle individual objects and their components
in a uniform manner. In our system, this can be applied to manage student groups. For example, a class
can be represented as an aggregate of students, allowing activities to be performed uniformly across
both individual students and groups (classes).

- Decorator Pattern: It allows adding behavior to each object dynamically without affecting the behavior
of other objects in the same class. In our SIMS, we can use this pattern to add additional functionalities
to user notifications. For example, basic notification functionality can be extended to include email
notifications, SMS notifications, and push notifications using decorations.

Finally, Behavioral design patterns play an equally important role. Because Behavioral design patterns
focus on communication between objects, encapsulating processes and interactions. Some popular
behavioral design patterns include Strategy, Observer, and Command.

- Observer pattern: The Observer pattern defines one-to-many dependencies between objects so that
when an object changes state, all its dependent objects are notified and updated automatically. In our
system, this can be used to notify students and teachers about schedule or score updates. For example,
when an administrator updates a student's grade, all observers (students and teachers) are notified of
the change.

- Strategy Pattern: The Strategy Pattern defines a group of algorithms, encapsulates each algorithm, and
makes them interchangeable. It allows the algorithm to change independently of the clients using it. In
SIMS, different scoring strategies can be encapsulated by this pattern. For example, we may have
different algorithms for grading based on assignments, tests, or projects. These algorithms can be
selected and applied at runtime based on course requirements.

- Command pattern: allows encapsulation of requests into independent objects, allowing request
processing, undoing, and logging. It separates the request sender and the executor, and allows for
extension and customization of actions.

Through this we can see that applying and designing design patterns not only helps improve the
structure and performance of the software, but also provides flexibility and ease of maintenance. It
brings many benefits to the system, while also providing specific requirements for the SIMS project.

63
Using the right design patterns can help increase modularity, reduce dependencies, and create highly
scalable and reusable software systems. By using these design patterns, our team can improve the
modularity, scalability, and maintainability of SIMS, creating an efficient and flexible system.

6.2. Influence of SOLID principles in design and developing SIMS

applications:

If we say that coming up with creative designs to create objects is important to meet the needs of the
project. The Snake Principle has an important influence on system design and development. During the
design and adoption process, our team found that using SOLID principles in the design and development
of a Student Information Management System (SIMS) greatly influenced the process design.

First, Single Responsibility Principle (SRP) states that a class should only have one reason to change. In a
SIMS system, SRP compliance means that each layer has a unique responsibility. For example, the
Student class is responsible for managing student information and behavior, while the Course class
handles course- related activities. This ensures that each class is focused on a specific task, making it
easier to understand, maintain, and modify.

Second, Open-Closed Principle (OCP) states that software entities should be open to extension but
closed to modification. In SIMS, this principle is expressed in the design of report generation modules. By
designing these modules to be extensible. This facilitates extension and reduces the risk of introducing
errors in existing source code.

Third, Liskov Substitution Principle (LSP) states that objects of a superclass can be replaced by objects of
its subclass without affecting the correctness of the program. In SIMS, compliance with the LSP ensures
that subclasses representing different types of students can be used interchangeably with the base
Student class. This maintains consistent behavior across all subclasses, allowing for polymorphic use and
easier maintenance.

Fourth, Interface Segregation Principle (ISP) is equally influential: customers should not be forced to rely
on interfaces they do not use. In SIMS, ISP compliance means designing interfaces specifically for the

64
needs of different types of users. Each user type has its own interface with methods specific to their
needs, freeing customers from reliance on unnecessary methods and reducing the risk of coupling
between unrelated components.

Finally, Dependency Inversion Principle (DIP) dictates that high-level modules should not depend on
low- level modules; both should depend on abstraction. In SIMS, DIP compliance ensures that high-level
modules responsible for business logic depend on abstractions (interfaces) instead of concrete
implementations. This provides flexibility as different implementations can be easily swapped in and out
without affecting higher level modules.

So we can see that by following SOLID principles, SIMS application design and development has
significantly influenced the design because it promotes modularity, flexibility and maintainability.
However, these principles help create a code base that is easier to understand, modify, and extend.
Changes can be made to the system without requiring extensive modifications to existing code, reducing
the risk of errors or unintended side effects. Additionally, adherence to SOLID principles promotes the
use of abstractions, allowing for better testability and easier integration of new components or modules.
It can be said that SOLID principles have a positive impact on SIMS application design and development,
leading to a more robust and adaptable software system that enhances future innovation.

65
VII. Conclusion:
In summary, as a team leader, the modernization of the student information system management
project for these universities provides a significant opportunity for our team at FPT. Emphasizing object-
oriented principles, including inheritance, polymorphism, abstraction, and encapsulation, in addition to
understanding relationships such as association, aggregation, and composition, we has laid a solid
foundation for robust system design. Implementing SOLID principles is important because it is critical for
long-term success. Next, designing a scalable architecture using ASP .NET Core and illustrating it with use
case, class, and package diagrams ensures clarity and alignment with project goals. judgment.
Furthermore, our focus is on establishing a comprehensive testing regime, including automated testing.
By defining test scope, creating scenarios, and executing tests methodically, we ensure application
accuracy and performance. Through meticulous planning, adherence to methods, we have successfully
provided important information for student information system management projects and met the
needs of universities in a timely manner. efficient and effective.

66
VIII. References:
1. Oloruntoba, S. (2020). SOLID: The First 5 Principles of Object Oriented Design | DigitalOcean. [online]
www.digitalocean.com. Available at:

https://www.digitalocean.com/community/conceptual-articles/s-o-l-i-d-the-first-five-principles-of-
object-oriented-design.

2. Visual Paradigm (2019). UML Class Diagram Tutorial. [online] Visual-paradigm.com. Available at:
https://www.visual-paradigm.com/guide/uml-unified-modeling-language/uml-class-diagram-tutorial/.

3. Rani, B. (2018). Unified Modeling Language (UML) | Class Diagrams - GeeksforGeeks. [online]
GeeksforGeeks. Available at:

https://www.geeksforgeeks.org/unified-modeling-language-uml-class-diagrams/.

4. InterviewBit (2022). Top Characteristics of Object Oriented Programming. [online] InterviewBit.


Available at:

https://www.interviewbit.com/blog/characteristics-of-object-oriented-programming/.

5. GeeksforGeeks. (2023). Package Diagram | Introduction, Elements, Use Cases and Benefits. [online]
Available at:

https://www.geeksforgeeks.org/package-diagram-introduction-elements-use-cases-and-benefits/.

6. GeeksforGeeks. (2023). Creational Design Patterns. [online] Available at:


https://www.geeksforgeeks.org/creational-design-pattern/.

7. GeeksforGeeks. (2023). Structural Design Patterns. [online] Available at:


https://www.geeksforgeeks.org/structural-design-patterns/.

67

You might also like