Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
thakertanya authored Nov 30, 2023
2 parents 562dd98 + d0dc6b9 commit a335150
Show file tree
Hide file tree
Showing 87 changed files with 3,994 additions and 19 deletions.
74 changes: 74 additions & 0 deletions Design_Patterns.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Design Patterns for Beginners

## Introduction
Design patterns are solutions to common problems encountered in software design. They provide a 'systematic' yet creative way to design and solve problems. When you're building software, you often face similar challenges, and design patterns offer a way to address these challenges in an efficient manner.

### Why Design Patterns?

1. **Reusability:** Design patterns promote code reusability. Once you understand and implement a design pattern, you can apply it to different projects and scenarios. Note that it is not a piece of code for you to copy and paste, but a certain way of thinking and solving problems.
- But it is not the same as _algorithm_, whose input and output satisfy a certain specifications. Design Patterns are more creative and applicable in software development, in the sense that it does not require a strict specification on its input.

2. **Maintainability:** Using design patterns results in cleaner and more maintainable code. They encapsulate specific behaviors, making it easier to modify or extend functionalities without affecting the entire codebase.

3. **Scalability:** Design patterns contribute to scalable and flexible software architecture. They help in building systems that can adapt to changing requirements and scale gracefully.


## Types of Design Patterns

### 1. Creational Patterns
Creational patterns focus on object creation mechanisms, dealing with the process of object instantiation.

### 2. Structural Patterns
Structural patterns are concerned with object composition, forming relationships between objects to create larger structures.

### 3. Behavioral Patterns
Behavioral patterns define ways for objects to communicate, encapsulating patterns of communication between objects.

## Simple yet Powerful Example
We briefly introduce a **Creational Pattern** to demonstrate how powerful and flexible design patterns are.

Suppose we are developing a software where transportation tools are involved. At first, we only support cars and busses. But as our product grows, we have the need to support more types of transportation tools, like airplanes and boats, etc. We can certainly create more classes, like we did for cars and busses. But sometimes all we care about is that they are methods of transportation, i.e., they can take people from one place to another place. Let's call that behavior `move()`.

Thus, we may define a shared interface between among these classes
```python
class Vehicle:
def move(self):
...
```

We can then define
```python
class Airplane(Vehicle):
def move(self):
...
```
and
```python
class Car(Vehicle):
def move(self):
...
```


This way, we don't need to worry about the exact details of 'how a car/plane/bicycle' moves, but knowing that they support `move()` is good enough.


## Helpful resources
### Online Courses:
- **Coursera - "Design Patterns" by the University of Alberta:**
- This online course covers design patterns using Java. It includes video lectures, quizzes, and programming assignments to reinforce the concepts.

### Websites and Tutorials:

- **[Refactoring Guru - Design Patterns](https://refactoring.guru/design-patterns):**
- This website provides a comprehensive guide to design patterns with examples in multiple programming languages. **EXTREMELY RECOMMENDED!**


- **[DZone - Design Patterns Refcard](https://dzone.com/refcardz/design-patterns):**
- DZone offers a concise reference card on design patterns, providing a quick overview of essential patterns.

### Online Communities:

- **[Stack Overflow - Design Patterns Questions](https://stackoverflow.com/questions/tagged/design-patterns):**
- Stack Overflow is an excellent place to find answers to specific design pattern-related questions and engage with the programming community.

1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ Potential Topics--
3. SOLID Principles
4. Code Smells
5. QA testing
6. Introduction to Conda (Python)
- Professionalism
1. Customer engagement
1. Meeting best practices
Expand Down
60 changes: 52 additions & 8 deletions Topics/Development_Process.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,23 +50,60 @@

### [Serverless Computing](./Development_Process/Serverless_AWS_Lambda.md)

## Introduction to Shells

### [Introduction to using Shell](./Development_Process/Shell/intro_to_shell.md)

## SOLID PRINCIPLES:

SOLID is a mnemonic acronym that represents a set of five very important software development principles which lead to code that is easier to read, maintain, and extend, leading to higher-quality software that is easier to evolve over time.

The SOLID principles are:

- Single Responsibility Principle (SRP): A class should only have one cause to change, according to the Single Responsibility Principle (SRP). According to this theory, a class ought to have just one duty, which implies that there ought to be just one motivation for change. This makes the class more understandable, maintainable, and reuseable as well as more flexible.
#### Single Responsibility Principle (SRP):
- A class should only have one cause to change, according to the Single Responsibility Principle (SRP). According to the Single Responsibility Principle (SRP), each class or module should focus on a single concern, ensuring ease of understanding and modification.

- **Advantage**: This principle promotes maintainability by isolating responsibilities, reducing potential bugs caused by interconnected changes. Each class or module focuses on a single concern, making it easier to understand, test, and modify.

#### Open/Closed Principle (OCP)
- Software entities (classes, modules, functions, etc.) should be available for extension but closed for modification, according to the available/Closed Principle (OCP). It means system should be able to introduce new functionality without requiring changes to the existing code. Interfaces, polymorphism, and generalization are used to accomplish this.

- **Advantage**: OCP achieves stability by encouraging developers to create adaptable and scalable systems that accommodate changes through extensions rather than direct modifications. This promotes a more stable codebase and reduces the risk of introducing bugs in previously functioning code.

#### Liskov Substitution Principle (LSP)
- Subtypes must be able to be used in place of their parent types. According to this concept, it should be possible to swap out objects from a superclass for objects from a subclass without having any negative effects on the program's correctness. This necessitates abiding by the superclass's compact.

- **Advantage**: This principle fosters code reusability and allows for easier substitution of objects within the same inheritance tree. It simplifies maintenance, reducing the need for extensive modifications when introducing new objects or making alterations within the hierarchy. It ensures that system evolution remains agile and manageable without causing extensive disruptions to the existing codebase.

#### Interface Segregation Principle (ISP)
- This principle suggests that clients should not be forced to depend on interfaces they do not use. Instead of one large interface, it's better to have multiple smaller, specific interfaces that cater to the exact needs of the clients.

- **Advantage**: Promotes flexibility and avoids unnecessary dependencies. This helps to avoid the creation of fat interfaces, which are interfaces that contain more methods than the client needs. Ultimately, ISP encourages a modular and precise approach to interface construction, contributing to better software architecture and maintainability.

- Open/Closed Principle (OCP): Software entities (classes, modules, functions, etc.) should be available for extension but closed for modification, according to the available/Closed Principle (OCP). According to this principle, a system should be able to introduce new functionality without requiring changes to the existing code. Interfaces, polymorphism, and generalization are used to accomplish this.
#### Dependency Inversion Principle (DIP)
- High-level modules should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend on details. Details should depend on abstractions. This principle suggests that classes should depend on abstractions rather than concrete implementations, which makes the system more flexible and easier to modify.

- Liskov Substitution Principle (LSP): Subtypes must be able to be used in place of their parent types. According to this concept, it should be possible to swap out objects from a superclass for objects from a subclass without having any negative effects on the program's correctness. This necessitates abiding by the superclass's compact.
- **Advantage**: Encourages loose coupling and easier maintenance of the system. This facilitates easier modifications, replacements, and testing, as changes in low-level modules don’t affect the higher-level ones.

- Interface Segregation Principle (ISP): Clients should not be forced to depend on interfaces they do not use. This principle states that a client should not be forced to implement an interface if it does not use all of the methods defined by the interface. This helps to avoid the creation of fat interfaces, which are interfaces that contain more methods than the client needs.
## Restaurant example of each principle

- Dependency Inversion Principle (DIP): High-level modules should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend on details. Details should depend on abstractions. This principle suggests that classes should depend on abstractions rather than concrete implementations, which makes the system more flexible and easier to modify.
#### SRP
Consider a **Chef** in a restaurant. Initially, the chef might handle multiple responsibilities: preparing dishes, managing inventory, and overseeing kitchen hygiene. Adhering to SRP, distinct roles are established. The chef focuses solely on cooking, while inventory management becomes the responsibility of a dedicated inventory manager.

## Resource that gives examples of the uses cases of SOLID principles
#### OCP
Suppose a restaurant offers a fixed menu, and every addition or modification requires altering the entire menu preparation process. Adhering to OCP, the menu system can be designed with a base menu class that remains closed for modification. New dishes or changes are introduced via an extension, such as a SpecialsMenu class, allowing additions without altering the existing menu. This principle enables the restaurant to introduce seasonal or daily specials without affecting the core menu.

#### LSP
Imagine a scenario where the restaurant's system expects all orders to be instances of a generic Order class. Adhering to LSP, any specialized order, like a delivery order, dine-in order, or takeaway order, should be substitutable for a standard order without breaking the system's functionality. Each specific order type should adhere to the expected behavior of the generic Order class, ensuring seamless substitution.

#### ISP
Consider a system where all employees (servers, chefs, and cleaners) are expected to use the same comprehensive Employee interface, including methods for serving tables, cooking dishes, and cleaning. Adhering to ISP, distinct interfaces are established for each role: ServerInterface, ChefInterface, and CleanerInterface. This segregation ensures that each role implements only the methods relevant to their responsibilities, preventing unnecessary method implementations.

#### DIP
Suppose the restaurant's ordering system directly depends on specific external services for payment processing and inventory updates. Adhering to DIP, the system can depend on abstract interfaces like PaymentProcessor and InventoryService, allowing flexibility to switch between different payment processors or inventory management systems without directly impacting the core ordering system. This abstraction and dependency on interfaces rather than concrete implementations facilitate adaptability and system maintenance.


## Resource that gives example of actual code of SOLID principles

LINK : https://www.youtube.com/watch?v=_jDNAf3CzeY

Expand Down Expand Up @@ -101,14 +138,21 @@ This is only a simplification of what "Clean Architecture" is; the topic is so v

- A very detailed explanation of Clean Architecture by Robert C. Martin or Uncle Bob and his book

- https://www.youtube.com/watch?v=2dKZ-dWaCiU
- https://github.com/ropalma/ICMC-USP/blob/master/Book%20-%20Clean%20Architecture%20-%20Robert%20Cecil%20Martin.pdf
- https://www.youtube.com/watch?v=2dKZ-dWaCiU
- https://github.com/ropalma/ICMC-USP/blob/master/Book%20-%20Clean%20Architecture%20-%20Robert%20Cecil%20Martin.pdf

## Code Smells

### [Code Smells](./Development_Process/Code_Smells.md)

## Clean coding
### [Coding and commenting styles](./Development_Process/clean_coding_styling.md)

## Prompt Engineering
### [Basics of Prompt Engineering](./Development_Process/Prompt_Engineering.md)

## Technical Documents
### [Intro to Request for Comments (RFCs)](./Development_Process/Technical_Documents/Intro_to_rfcs.md)


### [API documentation with SwaggerHub](./Development_Process/Documentation/Swagger_API_Documentation.md)
Loading

0 comments on commit a335150

Please sign in to comment.