Middle+
What tasks have you encountered when using design patterns?
sobes.tech AI
Answer from AI
Regarding improvement tasks:
- Maintainability and extensibility of code: Patterns made the code more readable and structured, simplifying changes and adding new functionality.
- Elimination of duplication: Factory methods or abstract factories helped centralize object creation.
- Solving typical problems:
- Object creation (Factory Method, Abstract Factory, Builder, Prototype, Singleton).
- Organizing interaction between objects (Strategy, Observer, Command, Mediator).
- Structuring classes and objects (Adapter, Decorator, Composite, Facade, Proxy).
- Increasing flexibility: Using Strategy to select algorithms depending on the context.
- Managing object lifecycle: Singleton to ensure a single instance of a class.
- Separation of concerns: Applying MVC (Model-View-Controller) or similar patterns to separate logic.
For example, I often used the Builder pattern to create complex objects with many optional parameters, which made the initialization code more readable and safe, avoiding issues with numerous overloaded constructors.
// Example of using Builder
public class User {
private final String firstName;
private final String lastName;
private final int age;
private final String phone;
private final String address;
// Private constructor
private User(Builder builder) {
this.firstName = builder.firstName;
this.lastName = builder.lastName;
this.age = builder.age;
this.phone = builder.phone;
this.address = builder.address;
}
// Getters
public static class Builder {
private final String firstName;
private final String lastName;
private int age = 0; // Default values
private String phone = "";
private String address = "";
public Builder(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public Builder age(int age) {
this.age = age;
return this;
}
public Builder phone(String phone) {
this.phone = phone;
return this;
}
public Builder address(String address) {
this.address = address;
return this;
}
public User build() {
return new User(this);
}
}
// Usage example
public static void main(String[] args) {
User user = new User.Builder("John", "Doe")
.age(30)
.phone("123-456-7890")
.build();
}
}
Also, Strategy is used to implement various sorting or data processing algorithms, allowing easy switching of the used algorithm without changing client code.
// Strategy interface
interface SortingStrategy {
void sort(int[] array);
}
// Bubble sort strategy
class BubbleSort implements SortingStrategy {
@Override
public void sort(int[] array) {
// Bubble sort logic
System.out.println("Sorting using Bubble Sort");
}
}
// Quick sort strategy
class QuickSort implements SortingStrategy {
@Override
public void sort(int[] array) {
// Quick sort logic
System.out.println("Sorting using Quick Sort");
}
}
// Context
class Sorter {
private SortingStrategy strategy;
public void setStrategy(SortingStrategy strategy) {
this.strategy = strategy;
}
public void performSort(int[] array) {
if (strategy != null) {
strategy.sort(array);
} else {
System.out.println("No sorting strategy set.");
}
}
// Usage example
public static void main(String[] args) {
Sorter sorter = new Sorter();
int[] data = {5, 2, 8, 1, 9};
sorter.setStrategy(new BubbleSort());
sorter.performSort(data);
sorter.setStrategy(new QuickSort());
sorter.performSort(data);
}
}