DevCezz

Programistyczny blog dla Ciebie

ocp
Wskazówki i porady

SOLID – Open/closed principle

Druga zasada mnemoniku SOLID. Praktyka mówiąca, że klasy powinny być otwarte na rozszerzenia, ale zamknięte na modyfikacje. Opracował ją Bertrand Meyer w 1988 r. Według niej dana encja powinna mieć możliwość zmiany swojego zachowania bez ingerowania w kod źródłowy. W ten sposób wytwarzamy system, który potrafi dostosować się do zmiennych wymagań.

Open/closed principle picture
Klasa zamyka się na modyfikacje, ale zawsze powinna być otwarta na rozszerzenie.

Tą zasadę można zilustrować następująco:

public class Manager {

	private Task task;

	public Manager(task) {
		this.task = task;
	}

	public void work() {
		switch(task) {
			case ORGANIZE_MEETINGS:
				organizeMeetings();
				break;
			case MOTIVATE_TEAM:
				motivateTeam();
				break;
			default:
				haveDayOff();
		}
	}
}

public enum Task {
	ORGANIZE_MEETINGS, MOTIVATE_TEAM
}

Przy tworzeniu obiektu Manager przekazujemy parametr odpowiadający pracy jaką ma dzisiaj do wykonania. W przypadku, gdyby doszedł nowy typ zadania niezbędna byłaby ingerencja w kod źródłowy. Z tego powodu należałoby w instrukcji switch obsłużyć nowy rodzaj pracy. Jest to uciążliwe dla programisty i zdecydowanie łamie zasadę Otwarte-Zamknięte. Rozwiązaniem tego zagadnienia jest przechowywanie wspólnego, niezmiennego zachowania w abstrakcji (klasie abstrakcyjnej albo interfejsie). W efekcie odmienne części kodu źródłowego należy zamieścić w klasach konkretnych rozszerzających daną abstrakcję.

public class Manager {
	private Task task;

	public Manager(task) {
		this.task = task;
	}

	public void work() {
		task.getTheJobDone();
	}
}

public interface Task {
	void getTheJobDone();
}

public class OrganizeMeetingsTask implements Task {

	@Override  
	public void getTheJobDone() {
		// do task - organize meetings
	}
}

public class MotivateTeamTask implements Task {

	@Override  
	public void getTheJobDone() {
		// do task - motivate team
	}
}

Taki sposób zapisu jest o wiele przyjemniejszy w utrzymaniu. Dzięki czemu dodając nowe typy zadań nie istnieje potrzeba zmiany implementacji klasy Manager. W rezultacie nasz kod źródłowy na pewno jest otwarty na rozszerzenia i zamknięty na modyfikacje 👍.

Podsumowanie

Osobiście uważam, że zasada Open/Closed Principle jest bardzo przydatna. Dzięki niej nasz kod jest mniej ze sobą powiązany i nie uzyskujemy zależności pomiędzy elementami. Trzymanie się tej reguły naprowadza nas na bardzo przydatny wzorzec architektoniczny jakim jest Strategia. Zachęcam do dyskusji na temat zasady Otwarte-Zamknięte poprzez napisanie komentarza pod postem lub wysłanie do mnie maila. Czy posiada ona same zalety, a może jednak ma jakieś wady, które nie przemawiają za nią? Może jesteś w stanie lepiej zilustrować tą regułę? Z chęcią się zapoznam z Twoim punktem widzenia!

Podziel się tym z innymi!