SlideShare a Scribd company logo
kgolev.com@kotseto
Writing SOLID Code
Kostadin Golev
CTO @ Rewards Labs
Преразказ с елементи на разсъждение
kgolev.com@kotseto
Програмирам > 10 години
Професионалните ми интереси
включват Аgile, DevOps и Test
automation. Горд баща на две деца.
Обичам да пиша, блога ми се намира на
kgolev.com
kgolev.com@kotseto
kgolev.com@kotseto
S ingle Responsibility Principle
O pen-Closed Principle
L iskov Substitution Principle
I nterface Segregation Principle
D ependency Inversion Principle
kgolev.com@kotseto
Не са закони
kgolev.com@kotseto
Инструменти или идеи
Помагат да взимаме по-добри решения
Приложими са в много и различни ситуации
Помагат да комуникираме по-добре
Ако има нещо, което ни харесва или не ни харесва в
нашия дизайн, много често можем да намерим
принцип, с който да го обясним
kgolev.com@kotseto
Бай Иван, крушката и
вентилатора
kgolev.com@kotseto
kgolev.com@kotseto
Всяка част от вашия код
трябва да прави едно нещо и
да го прави добре
kgolev.com@kotseto
Кода трябва да има само една
причина да се промени
kgolev.com@kotseto
class TaxiService {
void orderTaxi(String phone, String address) {
if (phone.length() < 7) {
throw new BadPhoneNumberException
(“Phone not valid!");
}
taxiPool.sendTaxi(address);
smsClient.sendMessage(phone,
"Your taxi is on the way!");
}
kgolev.com@kotseto
class TaxiService_V2 {
void orderTaxi(String phone, String address) {
if (phone.length() < 7
&& phone.length() > 12) { // <-- mistake
throw new BadPhoneNumberException
(“Phone not valid!");
}
taxiPool.sendTaxi(address);
smsClient.sendMessage(phone,
“Your taxi is on the way!");
}
kgolev.com@kotseto
boolean phoneIsNotValid(String phone) {
return phone.length() < 7
|| phone.length() > 12;
}
kgolev.com@kotseto
public class … {
public boolean phoneIsNotValid(String phone) {
return phone.length() < 7
|| phone.length() > 12;
}
}
kgolev.com@kotseto
class TaxiService_V3 {
void orderTaxi(String phone, String address) {
if (smsService.phoneIsNotValid(phone)) {
throw new BadPhoneNumberException
("Phone not valid!");
}
taxiPool.sendTaxi(address);
smsService.sendMessage(phone,
“Your taxi is on the way!");
}
kgolev.com@kotseto
• Кода ви е дълъг и прави много неща
• Трудно ви е да обясните какво прави едно
парче код
• Името на метода/класа който пишете няма
общо с кода, който разработвате
kgolev.com@kotseto
Стария телевизор
kgolev.com@kotseto
kgolev.com@kotseto
Софтуера трябва да бъде
затворен за модификация, но
отворен за надграждане
kgolev.com@kotseto
Customer silverCustomer = new Customer(SILVER);
getDiscountAmount(100, silverCustomer); // 10
Customer goldenCustomer = new Customer(GOLD);
getDiscountAmount(100, silverCustomer); // 20
kgolev.com@kotseto
double getDiscountAmount (int purchaseTotal,
Customer customer) {
double discount = 0;
switch (customer.type()) {
case SILVER:
discount = 0.1;
break;
case GOLD:
discount = 0.2;
break;
}
return discount * purchaseTotal;
}
kgolev.com@kotseto
class Customer {
double getDiscount() {
return 0;
}
}
kgolev.com@kotseto
class SilverCustomer extends Customer {
@Override
double getDiscount() {
return 0.1;
}
}
class GoldenCustomer extends Customer {
@Override
double getDiscount() {
return 0.2;
}
}
kgolev.com@kotseto
double getDiscountAmount_V2 (int purchaseTotal,
Customer customer) {
return customer.getDiscount() * purchaseTotal;
}
kgolev.com@kotseto
Добавянето на нова функционалност изисква
множество промени в стар код, вместо предимно
писане на нов
kgolev.com@kotseto
Салата с козе сирене
kgolev.com@kotseto
kgolev.com@kotseto
Всеки клас, който приема X като
параметър, трябва да може да
работи с всеки подклас на X
kgolev.com@kotseto
kgolev.com@kotseto
interface Duck {
void quack();
}
kgolev.com@kotseto
class RealDuck implements Duck {
@Override
public void quack() {
//quack code goes here!
}
}
kgolev.com@kotseto
Duck realDuck = new RealDuck();
realDuck.quack(); //works!
kgolev.com@kotseto
Duck duck = new ElectricDuck();
duck.quack(); //doesn't work?
kgolev.com@kotseto
class ElectricDuck implements Duck {
boolean turnedOn = false;
public void quack() {
if (turnedOn) {
//quack code goes here!
}
}
public void turnOn() { … }
}
kgolev.com@kotseto
if (duck instanceof ElectricDuck) {
((ElectricDuck)duck).turnOn();
}
duck.quack(); //now works!
kgolev.com@kotseto
class ElectricDuck_V2 implements Duck {
boolean turnedOn = false;
public void quack() {
if (!turnedOn) {
turnOn();
}
//quack code goes here!
}
public void turnOn() { … }
}
kgolev.com@kotseto
Duck anyDuck = new AnyKindOfDuck();
anyDuck.quack(); //always works
kgolev.com@kotseto
Накратко: не трябва кода да ви
изненада
kgolev.com@kotseto
• Замяната на типа на един клас променя
поведението му
• Налага се да проверяваме типа, за да избегнем
нежелано поведение
kgolev.com@kotseto
Групата по интереси
kgolev.com@kotseto
kgolev.com@kotseto
Не принуждавайте никой и нищо да зависи от
интерфейс който не му е нужен
kgolev.com@kotseto
interface Parent {
void takeCareOfChildren();
}
interface Programmer {
void code();
}
interface Driver {
void drive();
}
kgolev.com@kotseto
class Kostadin implements Parent, Programmer, … {
void takeCareOfChildren();
void code();
…
}
kgolev.com@kotseto
kgolev.com@kotseto
• Голям интерфейс с много методи
• Празна имплементация на метод от интерфейс,
който използваме
kgolev.com@kotseto
The Open Source Library
kgolev.com@kotseto
kgolev.com@kotseto
Смяната на двигателя не трябва да води до смяна
на автомобила
Depend upon abstractions
Do not depend on concretions
kgolev.com@kotseto
class OpelDiesel {
OpelDieselEngine engine;
OpelDiesel() {
engine = new OpelDieselEngine();
}
void start() {
engine.ignition();
}
}
kgolev.com@kotseto
class OpelGasoline {
OpelGasolineEngine engine;
OpelGasoline() {
engine = new OpelGasolineEngine();
}
void start() {
engine.ignition();
}
}
kgolev.com@kotseto
OpelDiesel car = new OpelDiesel();
car.start();
OpelGasoline carGasoline = new OpelGasoline();
carGasoline.start();
kgolev.com@kotseto
class Opel {
Engine engine;
Opel(Engine engine) {
this.engine = engine;
}
void start() {
engine.ignition();
}
}
kgolev.com@kotseto
class OpelDieselEngine implements Engine {
@Override
public void ignition() {
}
}
kgolev.com@kotseto
Opel dieselCar = new Opel(new OpelDieselEngine());
dieselCar.start();
Opel gasolineCar = new Opel(new OpelGasolineEngine());
dieselCar.start();
kgolev.com@kotseto
Opel oldOpel = new Opel(new VolgaEngine(),
new MoskvitchBrakes());
kgolev.com@kotseto
• Промяната или добавяне на модул води до
промени на модулите, които седят над него
(смяна на колата заради нов акумулатор)
• Модули на по-високо ниво (кола), зависят от
точно определени модули на ниско ниво
(двигател/акумулатор)
kgolev.com@kotseto
Software should be soft!
By Definition
kgolev.com@kotseto
Въпроси?
@kotseto
kgolev.com/talks/solid

More Related Content

PDF
Presentation on SOLID design principles
PDF
80 20@TUES
PPT
High Quality Code Introduction
PPT
Nakov High Quality Code
PDF
High level principles, micro-patterns and anti-patterns
PPTX
Курс по програмиране за напреднали (2012) - 1. Обектно-ориентирано програмира...
PPTX
Ambassador of telerik_academy
PPTX
Курс по програмиране за напреднали (2012) - 9. Добър и лош код. Преработка и ...
Presentation on SOLID design principles
80 20@TUES
High Quality Code Introduction
Nakov High Quality Code
High level principles, micro-patterns and anti-patterns
Курс по програмиране за напреднали (2012) - 1. Обектно-ориентирано програмира...
Ambassador of telerik_academy
Курс по програмиране за напреднали (2012) - 9. Добър и лош код. Преработка и ...

Similar to Writing SOLID Code (20)

PPTX
Курс по програмиране на C# 2013 - 7. Свойства. Индексатори. Наследяване. Изкл...
ODP
08. Objects
DOC
Introduction to Programming with C# Book - книга за C# програмиране
ODP
09. Strings
ODP
07. Functions
PPTX
Intro JS Development by Telerik Academy
ODT
Стар проект на Благо?!
PDF
Ruby 0
PPTX
Курс по програмиране на C# 2013 - 1. Въведение в компютърното програмиране и C#
PPTX
Училищен курс по програмиране на C# (2013/2014), занятие №7
DOC
Rykowodstwo po programirane_na_bazata_na_ezika_java
PPT
Introduction To Object Oriented Design and UML
ODP
04. Conditional Statements
PDF
Eclipse Editors@TUES (Part 2)
PPTX
Демо урок по програмиране със Светлин Наков
PPTX
Telerik Academy Introduction
PPTX
Училищен курс по програмиране на C# (2013/2014), занятие №1
PPTX
Как се става програмист?
PPT
Академия на Телерик - безплатни курсове 2011
PPTX
BG-IT-Edu: отворено учебно съдържание за ИТ учители
Курс по програмиране на C# 2013 - 7. Свойства. Индексатори. Наследяване. Изкл...
08. Objects
Introduction to Programming with C# Book - книга за C# програмиране
09. Strings
07. Functions
Intro JS Development by Telerik Academy
Стар проект на Благо?!
Ruby 0
Курс по програмиране на C# 2013 - 1. Въведение в компютърното програмиране и C#
Училищен курс по програмиране на C# (2013/2014), занятие №7
Rykowodstwo po programirane_na_bazata_na_ezika_java
Introduction To Object Oriented Design and UML
04. Conditional Statements
Eclipse Editors@TUES (Part 2)
Демо урок по програмиране със Светлин Наков
Telerik Academy Introduction
Училищен курс по програмиране на C# (2013/2014), занятие №1
Как се става програмист?
Академия на Телерик - безплатни курсове 2011
BG-IT-Edu: отворено учебно съдържание за ИТ учители

Writing SOLID Code