Wzorce projektowe to wielokrotnie użyteczne rozwiązania dla powtarzających się problemów projektowania oprogramowania. Natury OOP Javy i jej ekosystem sprawiają, że kilka wzorców jest szczególnie powszechnych — ich znajomość pomaga w rozpoznawaniu, komunikowaniu i stosowaniu sprawdzonych struktur. Dzielą się one na kategorie kreatywne, strukturalne i behawioralne.
Singleton (kreatywny) — jedna wspólna instancja
public class Config {
private static final Config INSTANCE = new Config(); // the single instance
private Config() {} // private constructor
public static Config getInstance() { return INSTANCE; }
}
// (enum singletons are an even safer idiom). Used for shared config, connection pools.
Factory (kreatywny) — hermetyzacja tworzenia obiektów
public static Shape createShape(String type) {
return switch (type) { // hides the concrete class from the caller
case "circle" -> new Circle();
case "square" -> new Square();
default -> throw new IllegalArgumentException();
};
}
// caller depends on Shape, not concrete classes — decoupling.
Builder (kreatywny) — konstruowanie złożonych obiektów krok po kroku
User user = new User.Builder()
.name("Ann")
.email("[email protected]")
.age(30)
.build(); // readable construction; avoids huge telescoping constructors
Strategy (behawioralny) — wymienne algorytmy
interface PaymentStrategy { void pay(double amount); }
class CreditCard implements PaymentStrategy { public void pay(double a) {...} }
class PayPal implements PaymentStrategy { public void pay(double a) {...} }
// swap behavior at runtime — lambdas make this trivial in modern Java
processor.setStrategy(new PayPal());
Observer (behawioralny) — publikowanie/subskrypcja
// subjects notify registered observers of changes (events, listeners)
button.addActionListener(e -> handleClick()); // GUI events use this everywhere
Decorator (strukturalny) — owijanie w celu dodania zachowania
// Java's I/O streams ARE the decorator pattern:
BufferedReader r = new BufferedReader(new FileReader("f.txt"));
// BufferedReader wraps FileReader, adding buffering
Gdzie wzorce pojawiają się w samej Javie
Singleton → Runtime.getRuntime()
Factory → Calendar.getInstance(), DriverManager
Builder → StringBuilder, Stream.Builder
Observer → event listeners, java.util.Observer
Decorator → java.io streams (BufferedReader wrapping FileReader)
Iterator → the Iterator interface / Collections
Strategy → Comparator, functional interfaces
Ostrzeżenie przed nadużyciem
Patterns are tools, not goals. Applying them where they don't fit ADDS complexity.
Use them when they genuinely solve your problem — many can be simpler with lambdas now.
Dlaczego to ważne
Wzorce projektowe stanowią wspólny słownik i sprawdzone rozwiązania dla typowych problemów projektowych, co jest cenne dla komunikacji ("użyj Strategy tutaj"), rozpoznawania struktur w istniejącym kodzie i unikania ponownego wymyślania wadliwych rozwiązań.
Pojawiają się one w całej bibliotece Javy (dekoratory I/O, metody fabryki, buildery, zdarzenia oparte na obserwatorze), więc ich zrozumienie pomaga w efektywnym używaniu i rozszerzaniu standardowej biblioteki.
Znajomość głównych wzorców — Singleton, Factory, Builder, Strategy, Observer, Decorator — i tego, gdzie każdy się sprawdza, jest charakterystyczna dla doświadczonych programistów i częstym tematem rozmów kwalifikacyjnych.
Równie ważna jest umiejętność stosowania ich w odpowiedni sposób (rozwiązywanie rzeczywistych problemów) zamiast ich wymuszania, szczególnie gdy nowoczesne funkcje, takie jak lambdy, upraszczają wiele klasycznych wzorców.
