Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
3 views

PROGRAM TITLE Applied Programming UNIT TITLE1

Uploaded by

lioi1fahuy
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

PROGRAM TITLE Applied Programming UNIT TITLE1

Uploaded by

lioi1fahuy
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 34

PROGRAM TITLE Applied Programming

UNIT TITLE: Applied Programming

ASSIGNMENT NUMBER: ASSIGNMENT 1

ASSIGNMENT NAME: Applied Programming

SUBMISSION DATE: 13/6/2023

DATE RECEIVED: 13/6/2023

TUTORIAL LECTURER: Nguyễn Ngọc Tân

WORD COUNT: 5181

STUDENT NAME: Trần Ngọc Huy

STUDENT ID: BKC13451

MOBILE NUMBER: 0585822025


Summative Feedback:

Internal verification:
Contents
Table of Contents
I. Investigate the impact of SOLID development principles on the OOP paradigm................................ 4
1. Investigate the characteristics of the object-orientated paradigm, including class relationships
and SOLID principles..................................................................................................................... 4
1.1.Presentation of object-oriented programming? Why object-oriented programming is widely
applied in large, complex software..................................................................................................... 4
1.2.Presentation of class and subject........................................................................................................ 4
1.3.2. Inheritance........................................................................................................................... 5
1.3.3 Polymorphism................................................................................................................................. 5
1.3.4. Abstraction..................................................................................................................................... 5
1.4.State relationships between classes: inheritance, association, aggregation........................................ 5
1.4.2. Affiliation (association)....................................................................................................... 6
1.4.3. Kết tập (aggregation/composition)...................................................................................... 6
1.5.Present the Solid principle: state the principles.................................................................................. 6
1.5.1. Single Responsibility Principle (SRP)................................................................................ 6
1.5.2. Open/Closed Principle (OCP)............................................................................................. 6
1.5.3. Nguyên tắc thay thế Liskov (Liskov Substitution Principle - LSP).................................... 6
1.5.4. Interface Segregation Principle (ISP).................................................................................. 6
1.5.5. Dependency Inversion Principle (DIP)............................................................................... 7
2. Explain how clean coding techniques can impact on the use of data structures and operations when
writing algorithms.............................................................................................................................. 7
2.2.Give ways to apply clean cod............................................................................................................. 7
2.3.Clean code is also applied in selecting appropriate data structures. When building an app that must
perform frequent searches, why use................................................................................................... 8
3. Analyse, with examples, each of the creational, structural and behavioural design pattern types.....9
3.2.Name the design pattern groups and design patterns in each group.................................................. 9
3.3.In each design pattern group, let's take a specific example that includes the diagram class and
implementation code........................................................................................................................ 10
 Class Diagram.................................................................................................................................. 10
• Class Diagram.................................................................................................................................. 13
II. Design a large dataset processing application using SOLID principles and clean coding techniques.
16
1. Design a large data set processing application, utilising SOLID principles, clean coding techniques
and a design pattern.......................................................................................................................... 16
2. Design a suitable testing regime for the application, including provision for automated testing....16
2.1.What is the presentation of testing? Why testing?........................................................................... 16
2.2.Presentation of unit testing, integration testing, system testing, user testing?................................. 16
III. Build a data processing application based ona developed design.................................................... 18
3.1. Build a large dataset processing application based on the design produced...................18
FILE MODEL........................................................................................................................................ 22
Application.java..................................................................................................................................... 26
3.2. Assess the effectiveness of using SOLID principles, clean coding techniques and
programming patterns on the application developed................................................................... 27
I. Perform automatic testing on a data processing application............................................................ 27
4.1. Examine the different methods of implementing automatic testing as designed in the test
plan. 27
BDD (Behavior-Driven Development):................................................................................................. 28
4.2. Implement automatic testing of the developed application............................................... 29
4.3. Discuss the differences between developer- produced and vendor- provided automatic
testing tools for applications and software systems..................................................................... 30
Vendor-Provided Automatic Testing Tools:.......................................................................................... 31
4.4. Analyse the benefits and drawbacks of different forms of automatic testing of
applications and software systems, with examples from the developed application...................31
Unit Testing:........................................................................................................................................... 31
Integration Testing:................................................................................................................................ 31
System Testing:...................................................................................................................................... 31
Performance Testing:............................................................................................................................. 31
Regression Testing:................................................................................................................................ 33
RENFERENCE...................................................................................................................................... 33
I. Investigate the impact of SOLID development principles on the OOP paradigm
1. Investigate the characteristics of the object-orientated paradigm, including class relationships
1.1. Presentation of object-oriented programming? Why object-oriented programming
is widely applied in large, complex software

Object-Oriented Programming (OOP) is a programming method widely applied in information


technology. Accordingly, the programmer focuses on creating objects and interactions between
those objects to solve problems in the program.

Object-oriented programming is a programming method that focuses on creating objects and


interactions between them to solve problems in a program. Each object is an instance of a class,
and a class defines properties and methods for its objects. The use of object-oriented
programming makes software development easier, maintained, and expanded. Object-oriented
programming is widely applied in large, complex software because it provides important benefits
such as source code reuse, ease of maintenance, ease of extension, clear structure, and high
reusabilityObject-oriented programming is a method that focuses on creating objects and
interacting between them to solve problems subject in the program. Each object is an instance of
a class that defines properties and methods. Object-oriented programming makes software
development easier, maintained, and extended. It is widely applied in large, complex software
because it provides important benefits such as source code reuse, ease of maintenance, ease of
extension, clear structure, and high reusability.

1.2. Presentation of class and subject.

Class and object are two basic concepts in object-oriented programming. A class is a template
that defines properties and methods for creating corresponding objects. An object is a specific
instance of a class with properties and methods defined in the class. The use of classes and
objects makes the source code easy to read and reuse, while minimizing dependencies between
program components.
For example, in a student management program, you can create a "Student" class and a "Course"
class to manage student information and corresponding courses. We can create objects from these
classes and link them to manage information about students and courses.

1.3.Presentation of properties: encapsulation, inheritance, polymorphism and state

1.3.1. Encapsulation
Encapsulation is a property that allows to hide the information and behavior of an object from the
outside. It protects the properties and methods of an object from direct external access, and
allows access only through public methods. Packaging makes program components independent
and protects them from unexpected external change.

1.3.2. Inheritance
Inheritance allows a class to be created based on an already existing class. The new class (child)
will inherit the properties and methods of the old class (parent) and can add new properties and
methods or override existing methods. Inheritance makes the program easy to read, maintain, and
minimizes repetition of source code.

1.3.3 Polymorphism
Polymorphism is the property that allows a method to take many different morphologies,
depending on the object called. Objects created from different classes can have the same method
name but have different implementations. Polymorphism makes the program flexible and
scalable.

1.3.4. Abstraction
Abstraction is a property that allows concealing the details of an object's settings and focusing
only on important properties and methods. It allows the creation of abstract or interface classes to
define important methods and properties for the corresponding objects, without regard to specific
settings. Abstraction makes the program easy to read, maintain, and extensible, and helps to
isolate the components of the program for independent development.

1.4. State relationships between classes: inheritance, association, aggregation

1.4.1. Inheritance
Inheritance is the relationship between a parent class and a child class, where the child class is
created based on the parent class and inherits the properties and methods of the parent class.
Inheritance helps create inherited subclasses and extends the properties and methods of the parent
class.
1.4.2. Affiliation (association)
A bond is a relationship between two layers, where each layer has access to the components of
the other. Linking helps create complex objects by combining simpler objects. Linked objects can
be objects of the same class or objects of different classes.

1.4.3. Kết tập (aggregation/composition)


Aggregation is the relationship between an object and a set of other objects. Aggregation can be
divided into two types: aggregation and composition. A generalized set is a relationship between
an object and a collection of other objects, in which objects in a set can exist without the object
they contain. A specific aggregation is a relationship between an object and a collection of other
objects, in which objects in a set exist only if the object containing them is created. Aggregation
helps create complex objects by combining simpler objects, and helps manage child objects of the
object they contain.

1.5. Present the Solid principle: state the principles.


The SOLID Principles are a set of software design principles introduced by Robert C. Martin
(also known as Uncle Bob) in 2000. The name SOLID is abbreviated from the first letters of
those principles:

1.5.1. Single Responsibility Principle (SRP)


A class should have only one responsibility, i.e. it should have only one reason to change. This
principle helps to separate the different features in an application and makes it easy to maintain
and extend the source code.

1.5.2. Open/Closed Principle (OCP)


A class should extend to add new features without modifying the old code. This principle makes
the program easy to maintain and extend, and minimizes the risk of changing the source code.
1.5.3. Nguyên tắc thay thế Liskov (Liskov Substitution Principle - LSP)
An object of the subclass can be used as an alternative to the object of the parent class without
changing the correctness of the program. This principle helps create subclasses that inherit and
identify with the parent class.

1.5.4. Interface Segregation Principle (ISP)


An interface should specify the methods that an object needs to work with it, rather than defining
many unnecessary methods. This principle helps to create interfaces that are simple and easy to
use.
1.5.5. Dependency Inversion Principle (DIP)
Modules depend on each other through abstraction, not implementation. This principle reduces
dependencies between modules in the program and creates modules that are independent and easy
to test.

2. Explain how clean coding techniques can impact on the use of data structures and
operations when writing algorithms.

2.1. What is a presentation of cleancode? Benefitsapply clean code.


Clean code is a simple, readable and easy-to-maintain method of writing code that makes it easy
for developers to understand and fix their code. Clean code is not just a way of writing code, but
a coding philosophy that helps create efficient software applications that meet customer needs
and are easy to maintain in the future.

Some of the benefits of applying clean code in software development include:

+ Easy to understand and fix

+ Easy to expand

+ Increased security

+ Increase reusability

+ Minimize errors

+ Increase efficiency

2.2. Give ways to apply clean cod


Here are some ways to apply clean code in software development:

1. Clearly name variables and functions: Clearly naming and accurately describing the function
of variables and functions makes the code easier to read and understand.

2. Keep the jaw short: The jaw should be kept short, not too long, and have only one
responsibility. Keeping functions short helps separate the different features in a function and
helps create independent and easy-to-maintain functions.

3. Use comments appropriately: Comments should be used to explain confusing code or special
functions of functions. However, comments should not be used to explain unreadable code or
to keep old code from being modified.

4. Use arguments and return values for their intended purpose: Function arguments and return
values should be used for their intended purpose. The purpose-driven use of arguments and
return values helps create independent functions that are easy to maintain.
5. Separate different features in a class: A class should have only one responsibility, i.e. it should
have only one reason to change. Separating different features within a class helps create classes
that are independent and easy to maintain.

6. Apply the SOLID principle: Apply the SOLID principles, including the Single Responsibility
Principle (SRP), Open/Closed Principle (OCP), Liskov Substitution Principle (LSP), Interface
Segregation Principle (ISP), and Dependency Inversion Principle (DIP) to create standalone
and easy-to-maintain modules in the application.

7. Use design patterns: Use design patterns to solve common programming problems and
create independent and easy-to-maintain modules and functions.

Use clean code tools: Use clean code tools such as SonarQube, PMD, Checkstyle, and
ReSharper to help test and improve the quality of your code.

8. Check and repair code regularly: Code should be tested and repaired regularly to minimize
the occurrence of bugs and increase the security and reliability of the application.

9. Code review: Codereview is the process of reviewing and evaluating other people's code to
find and fix bugs, improve the quality of code, and apply clean code principles in software
development. Code reviews help increase the quality of code, minimize errors and create higher
quality software products.

2.3. Clean code is also applied in selecting appropriate data structures. When building
an app that must perform frequent searches, why use
BinarySearch hơn Linear Search.

Clean code involves not only writing code that is easy to read and understand, but also includes
the use of appropriate data structures to optimize application performance.

In the case of searching for elements in an organized array, binary search is a more optimal
solution than linear search. The reason for this is that binary search can reduce the search time to
just O(log n), while Linear Search has an O(n) search time.

When using Linear Search, the order of the elements in the array does not matter. However, when
using Binary Search, the array must be sorted in advance. Otherwise, the use of Binary Search
will be ineffective and may lead to false results.

Therefore, when building an application that requires frequent searching, it is recommended to


choose the right data structure such as the arranged array and use Binary Search to optimize the
performance of the application. This will help reduce search time, improve performance, and
reduce the load on the application's servers.
3. Analyse, with examples, each of the creational, structural and behavioural design
pattern types

3.1. Explain the term "Design Pattern"?


Design Pattern is the term used to describe software design solutions used to solve common
problems in programming. Design patterns are often developed and packaged into a template that
can be reused in various software projects.

Design patterns are generally categorized into the following categories:

1. Creational Pattern: Object creation templates that make the creation of objects in the
application managed and optimized.

2. Structural Patterns: Structural patterns make organizing objects in the application easier and
more efficient.
3. Behavioral Patterns: Behavioral patterns make managing the activities of objects in the
application easier and more flexible.

Each design pattern will have different characteristics and uses, however, they are all created to
solve a specific problem in software design. The use of design patterns can make software
development easier, increase code uniformity and reusability, reduce code complexity, and
increase system maintainability.

3.2. Name the design pattern groups and design patterns in each group
Design patterns are an important concept in the field of software development, they are built to
solve repetitive problems during software development. The design pattern groups and design
patterns within each group include:

1. Creational Patterns: The design patterns in this group are used to create objects in the software.
- Abstract Factory Pattern

- Builder Pattern (Mẫu Builder)

- Factory Method Pattern (Mẫu Factory Method)

- Prototype Pattern (Mẫu Prototype)

- Singleton Pattern (Mẫu Singleton)

2. Structural Patterns: The design patterns in this group relate to the structure of objects and the
relationships between them.
- Adapter Pattern (Mẫu Adapter)

- Bridge Pattern (Mẫu Bridge)

- Composite Pattern(Mẫu Composite)

- Decorator Pattern (Mẫu Decorator)

- Facade Pattern (Mẫu Facade)

- Flyweight Pattern (Mẫu Flyweight)

- Proxy Pattern (Mẫu Proxy)

3. Behavioral Patterns: The design patterns in this group focus on how subjects interact with each
other and divide work.

- Chain of Responsibility Pattern (Mẫu Chain of Responsibility)

- Command Pattern (Mẫu Command)

- Interpreter Pattern (Mẫu Interpreter)

- Iterator Pattern (Mẫu Iterator)

- Mediator Pattern (Mẫu Mediator)

- Memento Pattern (Mẫu Memento)

- Observer Pattern (Mẫu Observer)

- State Pattern (Mẫu State)

- Strategy Pattern (Mẫu Strategy)

- Template Method Pattern (Mẫu Template Method)

- Visitor Pattern (Mẫu Visitor)

3.3. In each design pattern group, let's take a specific example that includes the
diagram class and implementation code.
3.3.1. Creational Design Pattern - Factory Method Pattern
 Class Diagram
 Code Implementation:

Main.java

public class Main {


public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();

Shape shape1 = shapeFactory.createShape("CIRCLE");


shape1.draw();

Shape shape2 = shapeFactory.createShape("RECTANGLE");


shape2.draw();
}
}

Circle.java
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}

Rectangle.java

public class Rectangle implements Shape {


@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}

Shape.java

public interface Shape {


void draw();
}

ShapeFactory.java

public class ShapeFactory {


public Shape createShape(String type) {
if (type.equalsIgnoreCase("CIRCLE")) {
return new Circle();
} else if (type.equalsIgnoreCase("RECTANGLE")) {
return new Rectangle();
}
return null;
}
}

Code running results

Inside Circle::draw() method.

Inside Rectangle::draw() method.


3.3.2. Structural Design Pattern - Decorator Patter
• Class Diagram

 Code Implementation:

Image.java

public interface Image {


void display();
String getPath();
}

public class BaseImage implements Image {


private String path;

public BaseImage(String path) {


this.path = path;
}

public void display()


{ System.out.println("Displaying " +
getPath());
}

public String getPath() {


return this.path;
}
Decorator
} implements Image.java

public abstract class Decorator implements Image {


protected Image wrappedImage;

public Decorator(Image image) {


this.wrappedImage = image;
}

public void display()


{ wrappedImage.display
();
}

public String getPath() {


return wrappedImage.getPath();
}
}
Border extends Decorator.java

public class Border extends Decorator {


public Border(Image image) {
super(image);
}

public void display() {


System.out.println("Adding border to " + getPath());
wrappedImage.display();
}

public void addBorder() {


System.out.println("Added border to " + getPath());
}
}

BaseImage.java

// Create a new BaseImage object


Image image = new BaseImage("path/to/image.png");
image.display();

// Add Border
image = new Border(image);
image.display();

// Adjust Brightness
image = new Brightness(image);
image.display();

Result:

Displaying image: path/to/image.png


Adding border to image
Displaying image: path/to/image.png
Adjusting brightness of image
Displaying image: path/to/image.png

kjj
II. Design a large dataset processing application using SOLID principles and clean coding
techniques.
1. Design a large data set processing application, utilising SOLID principles, clean
coding techniques and a design pattern.
2. Design a suitable testing regime for the application, including provision for automated
testing

2.1. What is the presentation of testing? Why testing?


Testing is the process of testing and evaluating the features, functionality, performance, and
reliability of a software or other technology product before it is released or widely used. The
purpose of testing is to find defects, flaws and weaknesses of the product so that they can be
corrected before the end user uses them.

Testing is considered an important part of the software development process as it helps to ensure
that the product works as expected and meets the requirements of the customer. If the product is
not adequately tested, it may experience issues such as software bugs, poor performance, weak
security, or failure to meet customer requirements.

In addition, testing helps to minimize risks and costs during product development. By checking
and detecting defects early, developers can fix them before the product is released, minimizing
the cost of repairs and increasing product stability.

2.2. Presentation of unit testing, integration testing, system testing, user testing?
Unit Testing Integration Testing System Testing User testing

Unit testing is the process Integration testing is the System testing is the User testing is the
of checking the correctness process of checking the process of checking the process of checking
of smaller software correctness of software correctness of the entire the correctness of
components, called units. put together, called software system, software from the
The goal of unit testing is integration. The goal of including software, perspective of the
to determine if the units are integration testing is to hardware, and other end user. The goal
functioning as designed, determine if the software components. The goal of of user testing is to
meet requirements and are has been properly system testing is to determine if the
error-free. Unit testing is integrated, interacted determine if the system software meets the
usually done by with each other properly, is functioning as user's needs, making
programmers and works properly as designed and meets user it easy
Programmer and use of designed requirements Usage and properties
techniques scheme. Integration not. Test Us
Testing
techniques such as path It is usually done by test Systems are usually availability does not.
inspection, boundary value engineers and uses implemented by test User testing is
inspection and limit techniques such as UI engineers and use usually done by
condition checking to testing, communication techniques such as UX/UI professionals
ensure the accuracy and mechanism testing, and performance testing, and uses techniques
reliability of the units. storage mechanism security testing and such as user
testing to ensure system stability testing to ensure experience testing,
operability. the accuracy and interoperability
reliability of the system. testing, and usability
testing to ensure
reasonableness and
responsiveness of
user requirements.

2.3. Give a specific example of JUNIT application in Sum


testing.java

public int sum(int[] numbers) {


int result = 0;
for (int i = 0; i < numbers.length; i++) {
result += numbers[i];
}
return result;
}

SumTest.java

import org.junit.Test;
import static org.junit.Assert.*;

public class SumTest {

@Test
public void testSum() {
Sum s = new Sum();
int[] numbers = {1, 2, 3, 4, 5};
assertEquals(15, s.sum(numbers));
}
}

In this test suite, we create a new Sum object and an integer array with values
between 1 and 5. We then call the sum() method of the Sum object and use the
assertEquals() method to compare the result returned with the expected value of
15.

If the sum() method works correctly, the test suite will run successfully and
return a "PASSED" result. If any error occurs, for example the method returns an
incorrect result, the test method will report an error and return a "FAILED"
result.

III. Build a data processing application based ona developed design.


3.1. Build a large dataset processing application based on the
design produced.
FILE DATA:

TypeBookShopData.java
package data;

public enum TypeBookData {


CSV, MY_SQL, API
}
BookData.interface
package data;

import Model.Book;

import java.util.List;

public interface BookData {


List<Book> getAllTitles();
}

CSVBookData.java
package data;

import Model.Book;
import Model.BookTmpl;
import com.opencsv.CSVReader;

import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;

public class CSVBookData implements BookData {

private String path;

public CSVBookData(String path) {


this.path = path;
}

@Override
public List<Book> getAllTitles() {
List<Book> bookList = new ArrayList<>();

ClassLoader classLoader = getClass().getClassLoader();


File file = new File(classLoader.getResource(path).getFile());

final int COL_ID = 0,


COL_ISBN = 5,
COL_TITLE = 9,
COL_AUTHORS = 7,
COL_RATING = 12,
COL_LANGUAGE = 11,
COL_YEAR = 8;

try (CSVReader csvReader = new CSVReader(new FileReader(file))) {


String[] row;
csvReader.readNext(); // Skip header row if present
while ((row = csvReader.readNext()) != null) {
BookTmpl tmpl = new BookTmpl();
tmpl.setId(row[COL_ID]);
tmpl.setIsbn(row[COL_ISBN]);
tmpl.setTitle(row[COL_TITLE]);
tmpl.setAuthors(row[COL_AUTHORS]);
tmpl.setRating(Double.parseDouble(row[COL_RATING]));
tmpl.setLanguage(row[COL_LANGUAGE]);
if (!row[COL_YEAR].isEmpty()) {

tmpl.setPublicationYear((int)Float.parseFloat(row[COL_YEAR]));
} else {
tmpl.setPublicationYear(0);
}
bookList.add(tmpl);
}
} catch (Exception e) {
e.printStackTrace();
}
return bookList;
}
}
APIBookData.java
package data;

import Model.Book;

import java.util.List;

public class APIBookData implements BookData {

public APIBookData(){
throw new RuntimeException("API not yet supported");
}
@Override
public List<Book> getAllTitles() {
return null;
}

MySqlBookData
package data;

import Model.Book;

import java.util.List;

public class MySQLBookData implements BookData {


public MySQLBookData() {
throw new RuntimeException("Not yet supported");
}
@Override
public List<Book> getAllTitles() {
return null;
}
}

FactoryBookShopData.java
package data;

public class FactoryBookData {


private FactoryBookData(){}

public static BookData getTitleData(TypeBookData


typeBookData){
switch (typeBookData){
case CSV:
return new CSVBookData("books.csv");
case MY_SQL:
return new MySQLBookData();
case API:
return new APIBookData();
default:
throw new RuntimeException("Not yet
supported!");
FILE MODEL

BookShop.interface
package Model;

public interface Book {


String getIsbn();
String getTitle();
String getAuthors();
double getRating();
int getRatingsCount();

int getPublicationYear();

String getLanguage();

BookShoplmpl.java
package Model;

public class BookTmpl implements Book {

private String id;


private String isbn;
private String title;
private String authors;
private double rating;
private int ratingsCount;
private int year;
private String language;
private int booksCount;
public BookTmpl() {
}

public void setId(String id) {


this.id = id;
}

public String getId() {


return id;
}
@Override
public String getIsbn() {
return null;
}

public void setIsbn(String isbn) {


this.isbn = isbn;
}

@Override
public String getTitle() {
return null;
}

public void setTitle(String title) {


this.title = title;
}

@Override
public String getAuthors() {
return null;
}

public void setAuthors(String authors) {


this.authors = authors;
}

@Override
public double getRating() {
return 0;
}

public void setRating(double rating) {


this.rating = rating;
}

@Override
public int getRatingsCount() {
return 0;
}

public void setRatingsCount(int ratingsCount) {


this.ratingsCount = ratingsCount;
}

@Override
public int getPublicationYear() {
return 0;
}

public void setPublicationYear(int year) {


this.year = year;
}

@Override
public String getLanguage() {
return null;
}

public void setLanguage(String language) {


this.language = language;
}

@Override
public int getBooksCount() {
return 0;
}

public void setBooksCount(int booksCount) {


this.booksCount = booksCount;
}

@Override
public String toString() {
return "BookTmpl{" +
"id='" + id + '\'' +
", isbn='" + isbn + '\'' +
", title='" + title + '\'' +
", authors='" + authors + '\'' +
", rating=" + rating +
", ratingsCount=" + ratingsCount +
", publicationYear=" + year +
", language='" + language + '\'' +
", booksCount=" + booksCount +
'}';
}
}
Application.java
import Model.Book;
import data.FactoryBookData;
import data.BookData;
import data.TypeBookData;

import java.util.*;

public class Application {

private static void menu(){


System.out.println("--- BOOK MANAGER ---");
System.out.println("1. List of books");
System.out.println("2. Search books by author, ISBN or title");
System.out.println("3. Sort by rating score ascending");
System.out.println("4. Take out the 10 books with the highest rating");
System.out.println("0. Exit");

}
public static void main(String[] args) {
BookData bookData = FactoryBookData.getTitleData(TypeBookData.CSV);

List<Book> books = bookData.getAllTitles();

Scanner in =new Scanner(System.in);


int choice = -1;
do {
menu();
choice =Integer.parseInt(in.nextLine());
switch (choice){
case 1:
System.out.println("List of books: ");
for (int i = 0; i < books.size(); i++){
System.out.printf("[ID = %d, ISBN = %s, Title= %s]\n",
i+1 , books.get(i).getIsbn(), books.get(i).getTitle());
}
break;
case 2:
System.out.println("Enter author name, ISBN or title: ");
String keyword = in.nextLine();
for (Book book : books){
if (book.getAuthors().contains(keyword) ||
book.getTitle().contains(keyword) || book.getIsbn().contains(keyword)){
System.out.println(book);
}
}
break;
case 3:
Collections.sort(books, new Comparator<Book>() {
public int compare(Book t1, Book t2) {
return Double.compare(t1.getRating(),
t2.getRating());
}
});
System.out.println("Books sorted by rating (ascending): ");
for (Book book : books) {
System.out.println(book);
}
break;
case 4:
List<Book> topRatedBooks = new ArrayList<>(books);

topRatedBooks.sort(Comparator.comparingDouble(Book::getRating).reversed());
topRatedBooks = topRatedBooks.subList(0,
Math.min(topRatedBooks.size(), 10));
System.out.println("Top 10 books with the highest rating: ");
for (Book book : topRatedBooks) {
System.out.println(book);
}
break;
default:
break;
}
}
while (choice != 0);
}
}

3.2. Assess the effectiveness of using SOLID principles, clean


coding techniques and programming patterns on the application
developed.
The application developed incorporates the principles of SOLID, clean coding
techniques, and design patterns effectively. It follows the SOLID principles, ensuring
single responsibility, extensibility, proper inheritance, interface segregation, and
dependency inversion. The code is clean and readable, with modular structure, proper
indentation, and meaningful naming. It also utilizes the factory method design pattern
to create different implementations based on the specified type. Overall, these practices
enhance code maintainability, extensibility, and testability, promoting good software
design principles.

I. Perform automatic testing on a data processing application

4.1. Examine the different methods of implementing


automatic testing as designed in the test plan.
TDD (Test-Driven Development)
TDD is a software development method in which writing test cases is done before
implementing the source code. The TDD development process typically includes the
following steps:
+ Write tests: First, write test cases to define the requirements and expected
behavior of the system. These tests will initially fail since there is no implemented
source code.
+ Run tests: Execute the test cases to verify that they fail due to the absence of
implemented source code.
+ Implement code: Implement the source code to fulfill the requirements of the test cases.
+ Rerun tests: Run the tests again to ensure that they pass after the source code
implementation.
+ Refactor code: Optimize the source code, improve the design, and restructure it to
ensure code quality after the implementation process.
BDD (Behavior-Driven Development):
BDD is a software development process that uses natural language to describe the
behavior of a system. BDD emphasizes the implementation of scenarios to define and
test the system's behavior. The BDD development process typically includes the
following steps:

+ Define scenarios: Use natural language to define scenarios that describe the desired
behavior of the system in different situations.
+ Write user stories: Write user stories to summarize the requirements from the
customer's perspective in various situations they expect the system to operate.
+ Write tests: Write tests to ensure that the defined scenarios and user stories are met.
Tests in BDD are often written in a format close to natural language.
+ Implement code: Implement the source code to fulfill the requirements of the
defined scenarios and user stories.
+ Run tests: Execute the tests to verify that the system meets the requirements of the
scenarios and user stories.
+ Refactor code: Optimize the source code, improve the design, and restructure it to
ensure code quality after the implementation process.

4.2. Implement automatic testing of the developed application.


ApplicationTest.java

import model.Book;
import model.BookImpl;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class ApplicationTest {


private static List<Book> books;

@BeforeAll
static void setup() {
// Mocking the book data for testing
books = new ArrayList<>();
books.add(new BookImpl(1, "1234567890", "Book 1", "Author 1", 4.5,
"English", 2020));
books.add(new BookImpl(2, "0987654321", "Book 2", "Author 2", 4.2,
"Spanish", 2019));
books.add(new BookImpl(3, "9876543210", "Book 3", "Author 1", 4.8,
"English", 2021));
}

@Test
void testSearchBooks() {
List<Book> searchResults = Application.searchBooks(books, "Author 1");
assertEquals(2, searchResults.size());
assertEquals("Book 1", searchResults.get(0).getTitle());
assertEquals("Book 3", searchResults.get(1).getTitle());
}

@Test
void testSortBooksByRating() {
List<Book> sortedBooks = new ArrayList<>(books);
Application.sortBooksByRating(sortedBooks);
assertEquals(4.2, sortedBooks.get(0).getAverageRating());
assertEquals(4.5, sortedBooks.get(1).getAverageRating());
assertEquals(4.8, sortedBooks.get(2).getAverageRating());
}

@Test
void testGetTopRatedBooks() {
List<Book> topRatedBooks = Application.getTopRatedBooks(books, 2);
assertEquals(2, topRatedBooks.size());
assertEquals("Book 3", topRatedBooks.get(0).getTitle());
assertEquals("Book 1", topRatedBooks.get(1).getTitle());
}
}

Result:

4.3. Discuss the differences between developer- produced


and vendor- provided automatic testing tools for applications
and software systems.
Developer-Produced Automatic Testing Tools:
+ Customization: Developer-produced testing tools often allow flexible
customization to fit specific project needs and development environments.
+ Domain Expertise: Developers have deep knowledge of the application and software
system, so the testing tools are developed based on their domain expertise and can
provide features and capabilities tailored to specific requirements.
+ Management and Support: Developers are responsible for managing and supporting
the testing tools, including providing updates, bug fixes, and technical support to users.
Vendor-Provided Automatic Testing Tools:
+ Standardization: Vendor-provided testing tools typically adhere to industry
standards and norms, ensuring consistency and compatibility in testing applications
and software systems.
+ Cross-Platform: Vendor-provided tools often support multiple platforms, running on
various environments, and can test applications and software systems across different
platforms.
+ Integration: Vendor-provided testing tools have the ability to integrate with other
software development tools, such as Integrated Development Environments (IDEs)
and source code management tools, enhancing the development and automated
testing process.

4.4. Analyse the benefits and drawbacks of different forms of


automatic testing of applications and software systems, with
examples from the developed application.

Automated testing in software applications and systems provides several benefits and
has some limitations.

Unit Testing:

Benefits: Ensures accuracy of individual components, quick bug identification and fixing.

Limitations: May overlook integration issues and system-level failures.

Integration Testing:

Benefits: Verifies interaction and compatibility between components, ensures correct


system functioning.

Limitations: Complex setup, difficult to cover all integration scenarios.

System Testing:

Benefits: Evaluates entire system behavior, ensures all components work together
correctly.

Limitations: Time-consuming, may not catch all edge cases or rare failures.

Performance Testing:

Benefits: Assess responsiveness, scalability, and stability, identifies performance issues.

Limitations: Requires realistic test scenarios, may not uncover all performance issues.

Acceptance Testing:

Benefits: Validates application meets user requirements and expectations.


Limitations: Relies on user expectations, may not cover all user scenarios.
Regression Testing:

Benefits: Ensures changes or updates do not introduce new defects, maintains stability.

Limitations: Time-consuming, requires comprehensive test cases.

RENFERENCE
https://www.svnhostingcomparison.com/lap-trinh-huong-doi-tuong-la-gi/
https://huongdancaidat.com/mot-so-cau-hoi-ve-oop-thuong-hoi-khi-di-phong-van/
https://topdev.vn/blog/oop-la-gi/

https://itviec.com/blog/oop-la-gi/

https://codegym.vn/blog/2022/12/26/oop-la-gi/

https://vntalking.com/nguyen-ly-solid-trong-node-js-voi-typescript.html https://laptrinhx.com/tim-hieu-
ve-nguyen-ly-solid-2609736131/ https://codelearn.io/sharing/ap-dung-nguyen-tac-solid-nhu-the-nao
https://laptrinhx.com/tim-hieu-ve-nguyen-ly-vang-solid-trong-lap-trinh-huong-doi-tuong- 1189430064/

You might also like