Java is a versatile, high-performance programming language widely used for developing applications ranging from mobile apps to large-scale enterprise systems. Here's why we chose Java for this project:
-
Platform Independence
Java's "Write Once, Run Anywhere" capability allows the application to run on any system with a Java Virtual Machine (JVM).
-
Strong Community & Ecosystem
Java has a rich ecosystem of libraries and frameworks and excellent support from a large community.
-
Object-Oriented & Scalable
Java’s object-oriented principles ensure modular and maintainable code, while its scalability makes it suitable for both small and enterprise-level applications.
-
Performance & Security
Modern JVMs optimize Java's performance to compete with lower-level languages, and built-in security features make it a trusted choice for secure applications.
-
Multithreading
Java supports concurrent programming, allowing the efficient execution of multiple tasks simultaneously, making it ideal for complex systems.
The Complex Numbers Calculator is an object-oriented application designed to perform various arithmetic operations (ADDITION, SUBSTRACTION, DIVISION, MULTIPLICATION) strictly on complex numbers.
The code remains modular and maintainable by adhering to OOP principles such as:
- DRY (Don't Repeat Yourself)
- SRP (Single Responsibility Principle)
Moreover, to enhance flexibility and scalability in the application's architecture, it utilizes Software Design Patterns such as:
To find more about the project, check the JavaDoc
using the following command based on your operating system
(make sure you are currently located in the project directory):
-
macOS
open ./src/resources/index.html
-
Linux
xdg-open ./src/resources/index.html
-
Windows
start .\src\resources\index.html
The Complex Numbers Calculator includes a various range of functionalities to perform arithmetic operations and manipulate complex numbers efficiently.
-
Arithmetic Operations
Let's consider two complex numbers z_1 and z_2 such that:
z_1 = a_1 + b_1 * i
z_2 = a_2 + b_2 * i
Where { a_1, b_1, a_2, b_2 } are considered Real Numbers
Based on their composition, we deduce the following operations.
- Addition
z_1 + z_2 = (a_1 + a_2) + (b_1 + b_2) * i
- Substraction
z_1 - z_2 = (a_1 - a_2) + (b_1 - b_2) * i
- Division
z_1 / z_2 = [(a_1 * a_2 + b_1 * b_2) + (b_1 * a_2 - a_1 * b_2) * i] / (a_2 ^ 2 + b_2 ^ 2)
- Multiplication
z_1 * z_2 = (a_1 * a_2 - b_1 * b_2) + (a_1 * b_2 + b_1 * a_2) * i
- Addition
-
Conjugate Calculation
The conjugate of a complex number is useful in various mathematical applications.
Let's consider one complex numbers z such that:
z = a + b * i
Where { a, b } are considered Real Numbers
Therefore, we define the conjugate as:
z = a - b * i
-
Input Parsing
The calculator can accept (via Command Line Interface / CLI) complex numbers in standard form (eg. a + b * i), allowing for intuitive user input.
-
Error Handling
Robust error handling for invalid inputs and operations, ensuring a smooth user experience.
-
Extensibility
The design supports easy addition of new features, such as advanced mathematical operations or graphical user interfaces, thanks to the application of OOP principles and design patterns.
Before installing and running the application, ensure that the following prerequisites are met:
You need JDK 8 or higher installed on your system. To check if it is installed, run in terminal:
java -version
If you don't have it installed, you can download the JDK from Oracle's official website.
To get started, clone the repository from GitHub to your local machine. In terminal, nagivate to the directory you where you want to store the project, and run:
git clone https://github.com/Mogalina/ComplexNumbersCalculator.git
Once you have cloned your project, navigate into the project directory:
cd ComplexNumbersCalculator
To compile the Java files, use the javac
command to compile all the files in the src
directory:
javac -d out -sourcepath src src/**/*.java
This command will do the following:
- Compile all the
.java
files located in the specified directories. - Store the compiled
.class
files in theout/
directory.
After compiling, you can run the application using the java
command. From your project root directory, execute the
main class that contains the main
method:
java -cp out Main
After installing the application, follow the steps below to run and use the Complex Numbers Calculator.
Once you’ve successfully built or compiled the project, you can run the application directly from the terminal or your IDE.
If you compiled the project using the JDK and the compiled files are located in the out/
directory, you can run the application using the java
command. Navigate to the root of your project and run:
java -cp out Main
If you’re using an IDE like IntelliJ IDEA or Eclipse, follow these steps:
- Open the project in your IDE.
- Locate the class containing the
main
method (usuallyMain.java
or equivalent). - Right-Click on the file and select
Run
. - The application will start, and you’ll be able to interact with it via the IDE's terminal.
The Complex Numbers Calculator supports a various range of arithmetic operations on complex numbers. You must
run the expression using the java
command in terminal as follows:
Each complex number must have the following structre with no spaces between: a+b*i
.
Between each operator and operand there must exist at least one space: a+b*i op c+d*i
. Operators
must be one of + - * /
.
To calculate the result of an arithmetic expression containing exclusively complex numbers, in terminal run the
following using java
command:
java -cp out Main complex_number operator complex_number operator complex_number ...
This class
represents the entry point of the application. It initializes the program, handles user input, and
orchestrates the calculation operations.
- Starts the application and manages user interactions.
- Creates an
ExpressionParser
object to handle the parsing and evaluation of the arithmetic expression.
This folder stores information about the application and project structure, including the relationship between classes
, packages
and modules
.
This .png
file represents the
UML (Unified Modeling Language) diagram that stores
information about the relationship between classes
, packages
and modules
.
This package
stores enum
classes to define collections of constants that are grouped together under a single
type. The purpose of enum
classes is to enhance type safety and make code more readable and
maintainable.
public enum Operation {
ADDITION,
SUBTRACTION,
MULTIPLICATION,
DIVISION
}
Defines the supported operations on arithmetic expressions.
This package
contains classes
that follow the
Factory Method Pattern. The purpose of this design
pattern is to use factory methods to deal with the problem of creating objects without having to specify their
exact classes.
This class
is responsible for creating expressions (subclasses
) that belong to the same family (class
), but with
different behaviors (ADDITION, SUBSTRACTION, MULTIPLICATION, DIVISION). It utilizes two key software
design patterns: the Factory Pattern and the
Singleton Pattern.
public ComplexExpression createExpression(@NotNull Operation operation, ComplexNumber[] args) {
return switch (operation) {
case ADDITION -> new AdditionExpression(args);
case SUBTRACTION -> new SubtractionExpression(args);
case MULTIPLICATION -> new MultiplicationExpression(args);
case DIVISION -> new DivisionExpression(args);
default -> throw new IllegalArgumentException("Unknown operation");
};
}
-
Encapsulation of Object Creation : The client code doesn’t need to know which specific class to instantiate, it just specifies the operation, and the factory handles the rest.
-
Flexibility and Extensibility : If more operations are added in the future, it’s easy to extend the factory to create instances of the new expression types without changing the client code.
-
Centralized Creation Logic : All logic for creating complex expression objects is centralized within the factory, promoting consistency and reducing code duplication across the application.
private ExpressionFactory() {}
The constructor
is private, preventing external classes
from instantiating it dirrectly.
private static ExpressionFactory instance = null;
The class
has a static variable instance
that holds the single instance of ExpressionFactory
.
public static ExpressionFactory getInstance() {
if (instance == null) {
instance = new ExpressionFactory();
}
return instance;
}
Checks if the instance
exists. If so, it initializes the instance
and returns it, otherwise it returns the already
created instance
. This ensures that the factory is only created when needed (Lazy Initialization).
Therefore, the benefits of using Singleton Method here are the following:
-
Resource Efficiency : Since this
class
is responsible for creatingComplexExpression
objects
, ensuring that only oneExpressionFactory
instance exists means fewer resources are used and the application avoids unnecessary object creation. -
Centralized Control : Having a single
instance
of the factory centralizes the creation logic forComplexExpression
objects
, allowing better control over how these objects are instantiated and ensures consistency. -
Global Access : Since the factory provides complex expressions for different parts of the application, the Singleton pattern ensures global access to the factory from anywhere in the codebase.
-
Separation of Concerns (SoC) : The
ExpressionFactory
isolates the creation ofComplexExpression
objects
from the client code, meaning the client only cares about using the created object, not how it’s created. -
Scalability : Adding new types of
ComplexExpression
objects
is easy. You only need to modify the factory method to handle new types of expressions, without needing to change the code that uses the factory. -
Controlled Instantiation : The Singleton Pattern ensures that only one
instance
of the factory exists, preventing multiple factories from being created unnecessarily and conserving memory resources.
This package
contains classes
that are the core domain objects of the application. These classes
represent
abstract concepts specific to the application.
This class
defines a complex number with real and imaginary parts.
Access | Type | Name | Description |
---|---|---|---|
private |
final int |
re |
Real part of the complex number. |
private |
final int |
im |
Imaginary part of the complex number. |
-
public ComplexNumber(int re, int im)
Constructs a new
ComplexNumber
with the specified real and imaginary parts. -
public ComplexNumber add(@NotNull ComplexNumber other)
Adds this complex number to another complex number.
-
public ComplexNumber subtract(@NotNull ComplexNumber other)
Subtracts another complex number from this complex number.
-
public ComplexNumber multiply(@NotNull ComplexNumber other)
Multiplies this complex number by another complex number.
-
public ComplexNumber divide(@NotNull ComplexNumber other)
Divides this complex number by another complex number.
-
public ComplexNumber conjugate()
Returns the conjugate of this complex number.
-
@Override public String toString()
Returns a string representation of the complex number.
Abstract class
representing an arithmetic expression involving complex numbers.
Access | Type | Name | Description |
---|---|---|---|
protected |
Operation |
operation |
The operation to be performed on the complex numbers. |
protected |
ComplexNumber[] |
args |
Array of complex numbers involved in the expression. |
-
public ComplexExpression(Operation operation, ComplexNumber[] args)
Constructor to initialize the complex expression with a specific operation and a list of complex numbers as arguments.
-
public ComplexNumber execute()
Executes the complex expression by sequentially applying the specified operation on all complex numbers provided as arguments.
-
protected abstract ComplexNumber executeOneOperation(ComplexNumber c1, ComplexNumber c2);
Abstract method to perform a single operation between two complex numbers.
Class representing a complex addition expression. This class
extends the ComplexExpression
class
.
-
public AdditionExpression(ComplexNumber[] args)
Constructor that initializes an addition expression with the given complex numbers.
-
@Override protected ComplexNumber executeOneOperation(@NotNull ComplexNumber c1, ComplexNumber c2)
Performs the addition of two complex numbers.
Class representing a complex substraction expression. This class
extends the ComplexExpression
class
.
-
public SubtractionExpression(ComplexNumber[] args)
Constructor that initializes a substraction expression with the given complex numbers.
-
@Override protected ComplexNumber executeOneOperation(@NotNull ComplexNumber c1, ComplexNumber c2)
Performs the substraction of two complex numbers.
Class representing a complex multiplication expression. This class
extends the ComplexExpression
class
.
-
public MultiplicationExpression(ComplexNumber[] args)
Constructor that initializes a multiplication expression with the given complex numbers.
-
@Override protected ComplexNumber executeOneOperation(@NotNull ComplexNumber c1, ComplexNumber c2)
Performs the multiplication of two complex numbers.
Class representing a complex division expression. This class
extends the ComplexExpression
class
.
-
public DivisionExpression(ComplexNumber[] args)
Constructor that initializes a multiplication expression with the given complex numbers.
-
@Override protected ComplexNumber executeOneOperation(@NotNull ComplexNumber c1, ComplexNumber c2)
Performs the division of two complex numbers.
Class responsible for parsing complex number expressions from CLI
.
Access | Type | Name | Description |
---|---|---|---|
private |
static final Pattern |
COMPLEX_NUMBER_PATTERN |
Regex to validate complex number format. |
-
public ComplexNumber parse(String @NotNull [] args)
Parses the command line arguments representing a complex number expression.
-
private boolean isComplexNumber(String str)
Checks if the given
string
is a valid complex number. -
private ComplexNumber parseComplexNumber(String str)
Parses a complex number from a
string
and returns aComplexNumber
object
. -
private boolean isOperator(@NotNull String str)
Checks if the given
string
is a valid operator. -
private ComplexExpression createExpression(ComplexNumber @NotNull [] numbers, String @NotNull [] operators)
Creates an
instance
ofComplexExpression
based on the parsed complex numbers and operators.
Based on the application Usage, you can run the following arithmetic expressions:
Run the arithmetic expression:
java -cp out Main 2+3*i + 5-6*i + -2+1*i
The returned result will be:
Expression result = 5-2*i
Run the arithmetic expression:
java -cp out Main 5-6*i - 2+3*i
The returned result will be:
Expression result = 3-9*i
Run the arithmetic expression:
java -cp out Main 17-6*i / 2+3*i
The returned result will be:
Expression result = 1-4*i
Run the arithmetic expression:
java -cp out Main 5-6*i * 2+3*i
The returned result will be:
Expression result = 28+3*i
Operation | Description | Example Input | Example Output |
---|---|---|---|
Addition | Adds two complex numbers. | 2+3*i + 5-6*i + -2+1*i |
5-2*i |
Subtraction | Subtracts the second complex number from the first. | 5-6*i - 2+3*i |
3-9*i |
Multiplication | Multiplies two complex numbers. | 5-6*i * 2+3*i |
28+3*i |
Division | Divides the first complex number by the second. | 17-6*i / 2+3*i |
1-4*i |