44
WRITING SOLID CODE преразказ с елементи на разсъждение Костадин Голев @kotseto github.com/kotse

Presentation on SOLID design principles

Embed Size (px)

Citation preview

Page 1: Presentation on SOLID design principles

WRITING SOLID CODEпреразказ с елементи на разсъждение

Костадин Голев@kotsetogithub.com/kotse

Page 2: Presentation on SOLID design principles

SOLID CODE ДИЗАЙН ПРИНЦИПИ

• Първоначално наречени “първите пет принципа” от чичо Боб

• SOLID e акроним, съставен от първата буква на всеки принцип

• Целят да ни помогнат да пишем код, който е по-лесен за четене, поддръжка и надграждане

Page 3: Presentation on SOLID design principles

КОИ СА SOLID ПРИНЦИПИТЕ?

• (S)ingle Responsibility Principle

• (O)pen-Closed Principle

• (L)iskov Substitution Principle

• (I)nterface segregation Principle

• (D)ependency inversion Principle

Page 4: Presentation on SOLID design principles

КАК ГИ ИЗПОЛЗВАМЕ?

• Не са правила или закони

• Идеи, които ни помагат в взимане на решения

• Служат като средство да комуникираме дизайна на кода, който пишем

• Ако имаме усещането, че един код е добър или лош, често можем да намерим принцип, който да обясни това

Page 5: Presentation on SOLID design principles

КРУШКАТА И ВЕНТИЛАТОРА

Page 6: Presentation on SOLID design principles

SINGLE RESPONSIBILITY PRINCIPLE

Всеки клас/функция/променлива трябва да прави едно нещо и да го прави добре

По-просто - само една причина да се промени

Page 7: Presentation on SOLID design principles
Page 8: Presentation on SOLID design principles

class TaxiService { public void orderTaxi(String phoneNumber, String address) { if (phone.length() < 7 || phone.length() > 12 || phone.contains(BAD_CHARACTERS)) { throw new Exception("Phone number not valid!"); }

Taxi taxi = taxiPool.getTaxi(address);

smsClient.sendMessage(phoneNumber, “Taxi on the way!”); }}

Page 9: Presentation on SOLID design principles

class TaxiService { boolean validatePhoneNumber() { if (phone.length() < 7 || phone.length() > 12 || phone.contains(BAD_CHARACTERS)) {

return false; }

return true; }

public void orderTaxi(String phoneNumber, String address) { if (!validatePhoneNumber(phoneNumber)) { throw new Exception("Phone number not valid!"); }

Taxi taxi = taxiPool.getTaxi(address); smsClient.sendMessage(phoneNumber, “Taxi on the way!”); }}

Page 10: Presentation on SOLID design principles

class SMSService { boolean validatePhoneNumber() { if (phone.length() < 7 || phone.length() > 12 || phone.contains(BAD_CHARACTERS)) {

return false; }

return true; }

void sendSms(String phoneNumber, String message) { smsClient.sendMessage(phoneNumber, “Taxi on the way”); }}

Page 11: Presentation on SOLID design principles

class TaxiService { SMSService smsService;

public void orderTaxi(String phoneNumber, String address) { if (smsService.validatePhoneNumber(phoneNumber)) { throw new Exception("Phone number not valid!"); }

Taxi taxi = taxiPool.getTaxi(address); smsService.sendSMS(phoneNumber, “Taxi on the way!”); }}

Page 12: Presentation on SOLID design principles

SUMMARY

• Може би най-труден за прилагане от петте принципа

• По-четим и лесен за преизползване код

• Код в един метод се асоциира с името на метода

• Името на всеки метод се асоциира с името на класа

Page 13: Presentation on SOLID design principles

СТАРИЯ ТЕЛЕВИЗОР

Page 14: Presentation on SOLID design principles

OPEN-CLOSED PRINCIPLE

Кодът, който пишем трябва да е отворен за разширение и затворен за модификация

Page 15: Presentation on SOLID design principles
Page 16: Presentation on SOLID design principles

class PaymentService { int calculatePayment (int amount, Customer customer) { double discount = 0;

switch (customer.type()) { case SILVER : discount = 0.1; break; case GOLD : discount = 0.2; break; ... ... }

amountToPay = amount - amount*discount;

return amountToPay; }}

Page 17: Presentation on SOLID design principles

class Customer { double getDiscount() { return 0; }}

class SilverCustomer extends Customer { double getDiscount() { return 0.1; }}

class GoldCustomer extends Customer { double getDiscount() { return 0.2; }}

Page 18: Presentation on SOLID design principles

class PaymentService {

int calculatePayment (int amount, Customer customer) { double discount = customer.getDiscount();

amountToPay = amount - amount*discount;

return amountToPay; }}

Page 19: Presentation on SOLID design principles

SUMMARY

• Вместо да променяме код, който вече работи, надграждаме го

• Използваме наследяване за целта

• Нарушаване на принципа води до много трудна поддръжка на кода, тъй като една малка промяна в един клас води до множество промени в други

Page 20: Presentation on SOLID design principles

САЛАТЕНИЯ БАР

Page 21: Presentation on SOLID design principles

LISKOV SUBSTITUTION PRINCIPLE

Обектите в програмата могат да бъдат заменени от наследниците им без промяна в тяхното

поведение

Page 22: Presentation on SOLID design principles
Page 23: Presentation on SOLID design principles

public interface Duck { public void papa();}

public class RealDuck implements Duck { public void papa() { //papa code goes here! }}

public class ElectricDuck implements Duck { public void papa() { if (turnedOn) { //papa code goes here! } }}

Page 24: Presentation on SOLID design principles

Duck realDuck = new RealDuck();duck.papa(); //works!

Duck electricDuck = new ElectricDuck();duck.papa(); //does not work!

if (duck instanceof ElectricDuck) { ((ElectricDuck)duck).turnOn();}duck.papa(); //now works!

Page 25: Presentation on SOLID design principles

class ElectricDuck implements Duck { public void turnOn() { turnedOn = true }

public void papa() { if (!turnedOn) { turnOn(); } //papa code goes here! }}

Duck duck = new AnyKindOfDuck();duck.papa(); //just works with all Ducks now!

Page 26: Presentation on SOLID design principles

SUMMARY

• Ако бъде нарушен, даден обект нарушава обичайното си “поведение”

• На практика представлява допълнение към Open-Closed принципа, като ни "повелява", че не можем едновременно да надградим един модул и да променим неговото поведение

Page 27: Presentation on SOLID design principles

КНИГАТА С РЕЦЕПТИ

Page 28: Presentation on SOLID design principles

INTERFACE SEGREGATION PRINCIPLE

Не принуждавайте кода си за зависи от неща, от които няма нужда

Page 29: Presentation on SOLID design principles
Page 30: Presentation on SOLID design principles

public interface Worker { public void work(); public void getPaid();}

public class RegularWorker implements Worker { public void work() {} public void getPaid() {}}

public class Manager { Worker worker;

public void setWorker(Worker worker) { this.worker = worker; }

public manage () { worker.work(); }}

Page 31: Presentation on SOLID design principles

public class Robot implements Worker { public void work() {} public void getPaid() {} ???}

Page 32: Presentation on SOLID design principles

interface IWork { public void work();}

interface IGetPaid { public void getPaid();}

class Worker implements IWork, IGetPaid { @Override public void work() {

}

@Override public void getPaid() {

}}

class Robot implements IWork { @Override public void work() {

}}

Page 33: Presentation on SOLID design principles

class Manager { IWork worker;

void setWorker(IWork worker) { this.worker = worker; }

void manage() { worker.work(); }}

Page 34: Presentation on SOLID design principles

SUMMARY

• Да се пише код, който да е лесен за разбиране е не по-малко важно от това кода да работи

• Интерфейсите ни помагат да опишем как трябва да работи кода, който пишем

• Множество малки интерфейси е по-добре от това да имаме един голям т.нар "замърсен" интерфейс

Page 35: Presentation on SOLID design principles

ФАБРИКАТА В ЛОВЕЧ

Page 36: Presentation on SOLID design principles

DEPENDENCY INVERSION PRINCIPLE

Зависимостите в кода е добре да се основават на абстракции, а не конкретни неща

Модулите на по-високо ниво в кода не трябва да зависят от тези на по-ниско

Page 37: Presentation on SOLID design principles
Page 38: Presentation on SOLID design principles

public class Steed5 { Diesel130HPEngine engine;

public Steed5() { engine = new Diesel130HPEngine(); }

public void start() { engine.ignition(); }}

Steed5 car = new Steed5();car.start();

Page 39: Presentation on SOLID design principles

public class Steed5V8 { V8Engine engine;

public Steed5V8() { engine = new V8Engine(); }

public void start() { engine.ignition(); }}

Page 40: Presentation on SOLID design principles

public interface Engine { public void ignition();}

public class V8Engine implements Engine { public void ignition () {}}

Engine engine = new V8Engine();Steed5 car = new Steed5(engine);car.start();

Page 41: Presentation on SOLID design principles

public class Steed5 { Engine engine;

public Steed5(Engine engine) { this.engine = engine; }

public void start() { engine.ignition(); }}

Page 42: Presentation on SOLID design principles

SUMMARY

• При нарушаване на принципа поддръжката на кода се затруднява значително

• Ако един модул се променя, той не трябва да променя модулите на по-високо ниво от неговото

Page 43: Presentation on SOLID design principles
Page 44: Presentation on SOLID design principles

Благодаря за вниманието!