Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes
4 changes: 2 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# Add project submodules
add_subdirectory(core)
add_subdirectory(controller)
add_subdirectory(patterns)
add_subdirectory(dp)
add_subdirectory(socket)
add_subdirectory(excercise)

Expand All @@ -24,7 +24,7 @@ add_executable(${PROJECT_NAME}
${CORE_SOURCES}
${SOCKET_SOURCES}
${CONTROLLER_SOURCES}
${DS_SOURCES}
${DP_SOURCES}
${EXCERCISE_SOURCES}
)

Expand Down
44 changes: 44 additions & 0 deletions src/ap/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
## Architecture Patterns
### 1. MVVM
- **MVVM (Model - View - ViewModel)** is an architecture pattern that separates the user interface (`View`) from the business logic and data (`Model`) through an intermediary component called the `ViewModel`
- **Components:**
- **Model**: responsible for managing and abstracting data sources (databases, APIs, ..).
`Model` and `ViewModel` work together to get and save the data.
- **View**: displays data provided by the `ViewModel` and informs the `ViewModel` about user actions. This layer observes the `ViewModel` and does not contain application logic.
- **ViewModel**: exposes data and state that are relevant to the `View`, and transforms data from Model into a suitable format. Moreover, it serves as a link between the `Model` and the `View`.
- **Binder** (Data Binding): connects the View and the ViewModel, automatically synchronizing data between them. This mechanism allows the View to update when the `ViewModel` changes, and vice versa.

- **Workflow:**
1. User interacts with the `View` (e.g., clicks a button).
2. The `View` notifies the `ViewModel`.
3. The `ViewModel` processes the input, applies logic, and may request data from the `Model`.
4. The `Model` fetches or updates the data (e.g., from an API or database).
5. The `Model` sends data back to the `ViewModel`.
6. The `ViewModel` updates the observable data, which automatically updates the `View` through `data binding or observers`.
```bash
User
View ↔ ViewModel ↔ Model # view automatically update
(data binding)
```
### 2. MVC
- **MVC (Model - View - Controller)** is an architectural pattern that separates the user interface (`View`) from the application logic and data (`Model`) using an intermediary component called the `Controller`.
- **Components:**
- **Model**: is responsible for managing and abstracting data sources (databases, APIs, etc.). The `Model` handles data retrieval, storage, and business logic.
- **View**: displays the data provided by the `Model` and represents the user interface. The `View` is responsible only for presentation and does not contain business logic.
- **Controller**: acts as an intermediary between the `View` and the `Model`. It receives user input from the `View`, processes it, and interacts with the `Model` to update or retrieve data. The `Controller` then determines which `View` should display the result.

- **Workflow:**
1. User interacts with the `View` (e.g., clicks a button).
2. The `View` sends the user input to the `Controller`.
3. The `Controller` processes the input, performs business logic, and may update the `Model`.
4. The `Model` updates its data (e.g., saves to a database or gets data from an API).
5. The `Controller` then updates the `View` based on the new `Model` data.
```bash
User
View → Controller → Model
View # view update manually
```
### 3. Examples
41 changes: 23 additions & 18 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,15 @@ set(CORE_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/datatypes/TypeConVersions.cpp

# Classes and object lifecycle
${CMAKE_CURRENT_SOURCE_DIR}/datatypes/class/Friend.cpp
${CMAKE_CURRENT_SOURCE_DIR}/datatypes/class/CConstructors.cpp
${CMAKE_CURRENT_SOURCE_DIR}/datatypes/class/CDestructors.cpp
${CMAKE_CURRENT_SOURCE_DIR}/datatypes/class/SallowDeepCopying.cpp
${CMAKE_CURRENT_SOURCE_DIR}/datatypes/class/RoleOfThreeFiveZero.cpp
${CMAKE_CURRENT_SOURCE_DIR}/datatypes/class/Relationship.cpp
${CMAKE_CURRENT_SOURCE_DIR}/datatypes/class/VirtualBase.cpp
${CMAKE_CURRENT_SOURCE_DIR}/datatypes/class/Binding.cpp
${CMAKE_CURRENT_SOURCE_DIR}/class/Friend.cpp
${CMAKE_CURRENT_SOURCE_DIR}/class/CConstructors.cpp
${CMAKE_CURRENT_SOURCE_DIR}/class/CDestructors.cpp
${CMAKE_CURRENT_SOURCE_DIR}/class/SallowDeepCopying.cpp
${CMAKE_CURRENT_SOURCE_DIR}/class/RoleOfThreeFiveZero.cpp
${CMAKE_CURRENT_SOURCE_DIR}/class/Relationship.cpp
${CMAKE_CURRENT_SOURCE_DIR}/class/VirtualBase.cpp
${CMAKE_CURRENT_SOURCE_DIR}/class/Binding.cpp
${CMAKE_CURRENT_SOURCE_DIR}/class/Encapsulation.cpp

# String handling
${CMAKE_CURRENT_SOURCE_DIR}/string/StringFormatting.cpp
Expand All @@ -57,20 +58,21 @@ set(CORE_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/filehandle/BinaryFileHandling.cpp

# STL containers and expressions
${CMAKE_CURRENT_SOURCE_DIR}/datatypes/container/sequence/Array.cpp
${CMAKE_CURRENT_SOURCE_DIR}/datatypes/container/sequence/Vector.cpp
${CMAKE_CURRENT_SOURCE_DIR}/datatypes/container/unordered/UnorderedMap.cpp
${CMAKE_CURRENT_SOURCE_DIR}/container/sequence/Array.cpp
${CMAKE_CURRENT_SOURCE_DIR}/container/sequence/Vector.cpp
${CMAKE_CURRENT_SOURCE_DIR}/container/unordered/UnorderedMap.cpp
${CMAKE_CURRENT_SOURCE_DIR}/container/adapter/Queue.cpp
${CMAKE_CURRENT_SOURCE_DIR}/container/adapter/Stack.cpp
${CMAKE_CURRENT_SOURCE_DIR}/container/sequence/Deque.cpp
${CMAKE_CURRENT_SOURCE_DIR}/container/associative/Set.cpp

${CMAKE_CURRENT_SOURCE_DIR}/expression/Lambda.cpp
${CMAKE_CURRENT_SOURCE_DIR}/expression/FunctionPointer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/datatypes/container/adapter/Queue.cpp
${CMAKE_CURRENT_SOURCE_DIR}/datatypes/container/adapter/Stack.cpp
${CMAKE_CURRENT_SOURCE_DIR}/datatypes/container/sequence/Deque.cpp
${CMAKE_CURRENT_SOURCE_DIR}/datatypes/container/associative/Set.cpp

# Smart pointers
${CMAKE_CURRENT_SOURCE_DIR}/datatypes/smart_pointer/Unique.cpp
${CMAKE_CURRENT_SOURCE_DIR}/datatypes/smart_pointer/Shared.cpp
${CMAKE_CURRENT_SOURCE_DIR}/datatypes/smart_pointer/Weak.cpp
${CMAKE_CURRENT_SOURCE_DIR}/smart_pointer/Unique.cpp
${CMAKE_CURRENT_SOURCE_DIR}/smart_pointer/Shared.cpp
${CMAKE_CURRENT_SOURCE_DIR}/smart_pointer/Weak.cpp

# Operator overloading
${CMAKE_CURRENT_SOURCE_DIR}/overloading/ArithmeticOperator.cpp
Expand All @@ -94,6 +96,9 @@ set(CORE_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/concurrency/RaceCondition.cpp
${CMAKE_CURRENT_SOURCE_DIR}/concurrency/ConditionVariable.cpp
${CMAKE_CURRENT_SOURCE_DIR}/concurrency/FuturePromise.cpp

# Utils
${CMAKE_CURRENT_SOURCE_DIR}/utils/StdAlgorithm.cpp
)

# Export CORE_SOURCES to the parent CMakeLists.txt
Expand Down
Empty file added src/core/class/Abstraction.cpp
Empty file.
File renamed without changes.
81 changes: 81 additions & 0 deletions src/core/class/Encapsulation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Encapsulation means grouping data and the functions that use that data
// inside a single unit, usually a class.

// Benefits of encapsulation:

// 1. Data Hiding
// The internal data of a class can be hidden from outside code.
// Other code cannot directly modify it, which helps protect the object's state.

// 2. Modularity
// Data and related functions are organized in one place.
// This makes the code easier to understand, maintain, and test.

// 3. Flexibility and Maintainability
// The internal implementation of a class can change without affecting
// the code that uses it, as long as the public interface stays the same.

// 4. Improved Security
// Restricting access to internal data helps prevent unintended or incorrect use.

// Implementation in C++:
// Encapsulation is implemented using access specifiers such as
// `private` and `protected` to restrict access to class members.
// Public getter and setter functions can be used to access or modify
// the internal data in a controlled way.

#include <ExampleRegistry.h>
#include <iostream>
#include <string>

namespace {
class Person {
private:
std::string name_;
int age_;

public:
Person(const std::string& name, int age) : name_(name), age_(age) {}

std::string getName() const { return name_; }
int getAge() const { return age_; }

void setAge(int age) {
if (age >= 0) {
age_ = age;
}
}

void introduce() const {
std::cout << "Name: " << name_ << ", Age: " << age_ << '\n';
}
};

void run() {
Person person("Alice", 25);

std::cout << "Initial state:\n";
person.introduce();

std::cout << "\nUpdating age through setter:\n";
person.setAge(30);
person.introduce();

std::cout << "\nAccessing data through getters:\n";
std::cout << "Name: " << person.getName() << '\n';
std::cout << "Age: " << person.getAge() << '\n';
}

} // namespace

class Encapsulation : public IExample {
std::string group() const override { return "core/class"; }
std::string name() const override { return "Encapsulation"; }
std::string description() const override {
return "Examples demonstrating encapsulation in C++";
}

void execute() override { run(); }
};

REGISTER_EXAMPLE(Encapsulation, "core/class", "Encapsulation");
File renamed without changes.
Empty file added src/core/class/Inheritance.cpp
Empty file.
Empty file added src/core/class/Polymorphism.cpp
Empty file.
File renamed without changes.
16 changes: 9 additions & 7 deletions src/core/concurrency/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@
## 2. Thread <thread>
- Threads are `the basic unit of` multitasking.
- There are many errors and risks associated with concurrency, including:
- `Deadlocks`: `refers to the situation where` two or more threads are blocked, `waiting for each other indefinitely`.
- `Race condition`: `refers to the situation where` two or more threads access `shared data` concurrently, leading to the `undefined behavior`.
- `Starvation`: `refer to the situation where` a thread `is unable to gain` regular access to the shared resources.
- `Deadlocks`: `refers to the situation where` two or more threads are blocked, `waiting for each other indefinitely`.
- `Race condition`: `refers to the situation where` two or more threads access `shared data` concurrently, leading to the `undefined behavior`.
- `Starvation`: `refer to the situation where` a thread `is unable to gain` regular access to the shared resources.
=> We can avoid these problems by `proper synchronization` between the threads.
- Use threads if we need to run long-lived and complex tasks.

### 2.2. Thead Synchronization
- The synchronization can be done by using the following components:
- `Mutex/Lock`: <mutex> they are used to protect the shared resouces, ensure that only one thread can access `the critical sections` at a time.
- `Semaphore`:
- `Futures and Promises`: <future>, <promise> are used for the asynchronous task execution.
- `Condition variable`: <condition_variable>
- `Mutex/Lock`: `<mutex>` they are used to protect the shared resouces, ensure that only one thread can access `the critical sections` at a time.
- `Semaphore`:
- `Futures and Promises`: `<future>`, `<promise>` are used for the asynchronous task execution.
- `Condition variable`: `<condition_variable>`

### 2.3. Thread Management
- `thread`: an `OS thread` `managed by` the kernel.
Expand Down Expand Up @@ -208,6 +208,8 @@ Back in main(), data = Example data after processing
```cpp
auto future = std::async(std::launch::async,some_function, arg_1, arg_2);
```
![future](../../../docs/image/future_promis.png)
![future_flow](../../../docs/image/future_promis_flow.png)
- e.g.
```cpp
// Pass in function pointer
Expand Down
File renamed without changes.
38 changes: 38 additions & 0 deletions src/core/utils/StdAlgorithm.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <algorithm>
#include <iostream>

#include "ExampleRegistry.h"

namespace FindIfExample {
void run() {
std::cout << "std::find_if example\n";
std::vector<int> v{1, 2, 3, 4, 5};
auto it = std::find_if(v.begin(), v.end(), [](int i) { return i % 2 == 0; });
if (it != v.end()) {
std::cout << "First even number: " << *it << '\n';
} else {
std::cout << "No even number found\n";
}

std::cout << "std::find_if_not example\n";
auto it_not =
std::find_if_not(v.begin(), v.end(), [](int i) { return i % 2 == 0; });
if (it_not != v.end()) {
std::cout << "First odd number: " << *it_not << '\n';
} else {
std::cout << "No odd number found\n";
}
}
} // namespace FindIfExample

class StdAlgorithm : public IExample {
std::string group() const override { return "core/utils"; }
std::string name() const override { return "StdAlgorithm"; }
std::string description() const override {
return "The examples for <algorithm> header";
}

void execute() override { FindIfExample::run(); }
};

REGISTER_EXAMPLE(StdAlgorithm, "core/utils", "StdAlgorithm");
4 changes: 2 additions & 2 deletions src/patterns/CMakeLists.txt → src/dp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
set(DS_SOURCES
set(DP_SOURCES

# Structural Patterns
${CMAKE_CURRENT_SOURCE_DIR}/structural/Adapter.cpp
Expand Down Expand Up @@ -29,4 +29,4 @@ set(DS_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/creational/Prototype.cpp
)

set(DS_SOURCES ${DS_SOURCES} PARENT_SCOPE)
set(DP_SOURCES ${DP_SOURCES} PARENT_SCOPE)
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,11 @@ void run() {

class ChainOfResponsibilityExample : public IExample {
public:
std::string group() const override { return "patterns/behavioral"; }
std::string group() const override { return "dp/behavioral"; }
std::string name() const override { return "ChainOfResponsibility"; }
std::string description() const override { return "CoR Pattern Example"; }
void execute() override { CoR::run(); }
};

REGISTER_EXAMPLE(ChainOfResponsibilityExample, "patterns/behavioral",
REGISTER_EXAMPLE(ChainOfResponsibilityExample, "dp/behavioral",
"ChainOfResponsibility");
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,10 @@ void run() {

class CommandExample : public IExample {
public:
std::string group() const override { return "patterns/behavioral"; }
std::string group() const override { return "dp/behavioral"; }
std::string name() const override { return "Command"; }
std::string description() const override { return "Command Pattern Example"; }
void execute() override { Command::run(); }
};

REGISTER_EXAMPLE(CommandExample, "patterns/behavioral", "Command");
REGISTER_EXAMPLE(CommandExample, "dp/behavioral", "Command");
Original file line number Diff line number Diff line change
Expand Up @@ -200,12 +200,12 @@ void run() {

class IteratorExample : public IExample {
public:
std::string group() const override { return "patterns/behavioral"; }
std::string group() const override { return "dp/behavioral"; }
std::string name() const override { return "Iterator"; }
std::string description() const override {
return "Iterator Pattern Example";
}
void execute() override { Iterator::run(); }
};

REGISTER_EXAMPLE(IteratorExample, "patterns/behavioral", "Iterator");
REGISTER_EXAMPLE(IteratorExample, "dp/behavioral", "Iterator");
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,12 @@ void run() {

class MediatorExample : public IExample {
public:
std::string group() const override { return "patterns/behavioral"; }
std::string group() const override { return "dp/behavioral"; }
std::string name() const override { return "Mediator"; }
std::string description() const override {
return "Mediator Pattern Example";
}
void execute() override { Mediator::run(); }
};

REGISTER_EXAMPLE(MediatorExample, "patterns/behavioral", "Mediator");
REGISTER_EXAMPLE(MediatorExample, "dp/behavioral", "Mediator");
Original file line number Diff line number Diff line change
Expand Up @@ -195,12 +195,12 @@ void run() {

class MementoExample : public IExample {
public:
std::string group() const override { return "patterns/behavioral"; }
std::string group() const override { return "dp/behavioral"; }
std::string name() const override { return "Memento"; }
std::string description() const override {
return "Memento Pattern Example ";
}
void execute() override { Memento::run(); }
};

REGISTER_EXAMPLE(MementoExample, "patterns/behavioral", "Memento");
REGISTER_EXAMPLE(MementoExample, "dp/behavioral", "Memento");
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,12 @@ void run() {

class ObserverExample : public IExample {
public:
std::string group() const override { return "patterns/behavioral"; }
std::string group() const override { return "dp/behavioral"; }
std::string name() const override { return "Observer"; }
std::string description() const override {
return "Observer Pattern Example";
}
void execute() override { Observer::run(); }
};

REGISTER_EXAMPLE(ObserverExample, "patterns/behavioral", "Observer");
REGISTER_EXAMPLE(ObserverExample, "dp/behavioral", "Observer");
Loading
Loading