Pobierz prezentację
Pobieranie prezentacji. Proszę czekać
1
Programowanie Obiektowe – Wykład 7
dr Piotr Jastrzębski Wydział Matematyki i Informatyki
2
Tematyka wykładu Zasady dobrego programowania
Zasady programowania obiektowego S.O.L.I.D. Obsługa wyjątków
3
Filary programowania obiektowego
Abstrakcja Hermetyzacja Dziedziczenie Polimorfizm
4
Zasady dobrego oprogramowania
Keep it Simple Stupid (KISS) - Buzi (Bez Udziwnień Zapisu, Idioto) Don’t Repeat Yourself (DRY) Tell Don’t Ask You Aren't Gonna Need It (YAGNI) Separation of Concerns
5
Keep it Simple Stupid (KISS) - Buzi (Bez Udziwnień Zapisu, Idioto)
kod ma być prosty i zrozumiały unikanie skomplikowanych zapisów nie oznacza upraszczania za wszelką cenę
6
Don’t Repeat Yourself (DRY)
unikanie powtórzeń w kodzie – u nas to np. polimorficzność, stałe oddzielenie powtarzającej się części od metody zalety: unikanie błędów, poprawki możemy dodać w jednym miejscu
7
Tell Don’t Ask związane z hermetyzacją i podziałem obowiązków
należy mówić obiektom jakie akcje mają wykonywać nie należy uzależnia wykonania akcji od stanu w jakim znajdują się obiekty
8
public class TDA_ZłyPrzykład { public void ObliczCene(Pojazd pojazd, Kalkulator kalkulator, int znizka) var cenaNetto = znizka > 5 ? pojazd.cenaKoncowa : pojazd.cenaKoncowa ; if (cenaNetto > kalkulator.cenaPodstawowa) kalkulator.DoliczAkcesoria(); } else // bez akcesoriów public class Kalkulator internal int cenaPodstawowa; public void DoliczAkcesoria() public class Pojazd internal int cenaKoncowa;
9
public class TDA_DobryPrzyklad { public void ObliczCene(Pojazd pojazd, Kalkulator kalkulator, int znizka) kalkulator.ObliczCeneNetto(pojazd, znizka); } public class Kalkulator internal int cenaPodstawowa; public void ObliczCeneNetto(Pojazd pojazd, int znizka) var cenaNetto = znizka > 5 ? pojazd.cenaKoncowa : pojazd.cenaKoncowa ; if (cenaNetto > this.cenaPodstawowa) this.DodajAkcesoria(); else // bez akcesoriów private void DodajAkcesoria() { } public class Pojazd internal int cenaKoncowa;
10
You Aren't Gonna Need It (YAGNI)
tworzenie tego co jest potrzebne i niezbędne usuwanie dodatków, które mogą się przydać np. usunięcie zbędnych usingów, zwolnienie zasobów, usuwanie nie używanych zmiennych, metod Cytat: Antoine de Saint-Exupéry Perfekcję osiąga się wtedy, gdy nie można już nic odjąć, a nie dodać.
11
Separation of Concerns
elementy składowe (np. klasy i metody) powinny być rozłączne i mieć oddzielne zastosowanie te elementy nie powinny współdzielić odpowiedzialności Cytat: Albert Einstein Wszystko trzeba robić tak prosto, jak to tylko jest możliwe, ale nie prościej.
12
Zasady programowania obiektowego S.O.L.I.D.
Single Responsibility Principle (SRP) – zasada jednej odpowiedzialności Open-Closed Principle (OCP) – zasada otwarte- zamknięte Liskov Substitution Principle (LSP) – Zasada podstawienia Liskov Interface Segregation Principle (ISP) – Zasada segregacji interfejsów Dependency Inversion Principle (DIP) – Zasada odwrócenia zależności
13
Zasada jednej odpowiedzialności
każdy obiekt powinien mieć tylko jeden cel i odpowiedzialność nie powinien istnieć więcej niż jeden powód do modyfikacji klasy jeśli jest kilka odpowiedzialności, powinniśmy podzielić klasę podobne do Separation of Concerns
14
Przykład public interface ISilnik { void ZmniejszObroty(); void ZwiejszObroty(); void AktualneObroty(); }
15
Przykład class Silnik : ISilnik { public void AktualneObroty() throw new NotImplementedException(); } public void ZmniejszObroty() public void ZwiejszObroty()
16
Przykład – źle! public interface ISilnik { void ZmniejszObroty(); void ZwiejszObroty(); void AktualneObroty(); //biegi void BiegWDol(); void BiegWGore(); }
17
Przykład – dobrze! public interface ISkrzynia { void BiegWDol(); void BiegWGore(); } class Skrzynia : ISkrzynia public void BiegWDol() throw new NotImplementedException(); public void BiegWGore()
18
Zasada otwarte-zamknięte
klasa powinna być otwarta na rozbudowę ,ale zamknięta do jej własnej modyfikacji możemy dodawać nowe pola i metody, ale bez zmiany w wewnętrzną strukturę zmiana istniejącej struktury może mieć wpływ na inne elementy hermetyzacja, dziedziczenie, polimorfizm, delegaty unikamy instrukcji warunkowych
19
Przykład enum DietType { Lose, Keep, Put } class Person internal DietType Diet; internal string Name;
20
Przykład – źle! public void ServeAMeal(List<Person> persons) { foreach (var person in persons) if(person.Diet == DietType.Lose) Console.WriteLine("Serwuj mniejsza porcje"); else if(person.Diet == DietType.Keep) Console.WriteLine("Serwuj standardowa porcje"); else if(person.Diet == DietType.Put) Console.WriteLine("Serwuj powiekszona porcje"); }
21
Przykład – dobrze! public void ServeAMeal(List<Person> persons, Dictionary<DietType, string> meals) { foreach (var person in persons) serve(person, meals); } private void serve(Person person, Dictionary<DietType, string> meals) string meal; if (meals.TryGetValue(person.Diet, out meal)) Console.WriteLine(meal);
22
Zasada podstawienia Liskov
powinniśmy być w stanie używać klasy pochodnej w miejsce klasy nadrzędnej i ona zachowuje się w taki sam sposób, bez modyfikacji klasa pochodna nie ma wpływu na zachowanie klasy nadrzędnej w hierarchii klas powinno dać się traktować obiekt klas pochodneh jak obiekt klas bazowej dziedziczenie ma być stosowane tylko gdy chcemy skorzystać z polimorfizmu, a nie tylko gdy chcemy wyciągnąć wspólne cechy
23
Przykład – źle! class Frezarka { public void Operacja() Console.WriteLine("Frezarka robi coś"); } class Obrabiarka : Frezarka Console.WriteLine("Obrabiarka robi coś");
24
Przykład – źle! Obrabiarka obr = new Obrabiarka(); obr.Operacja(); //Wynik: "Obrabiarka robi coś" Frezarka frez = obr; frez.Operacja(); //Wynik: "Frezarka robi coś"
25
Przykład – dobrze! class Frezarka { public virtual void Operacja() Console.WriteLine("Frezarka robi coś"); } class Obrabiarka : Frezarka public override void Operacja() Console.WriteLine("Obrabiarka robi coś");
26
Przykład – dobrze! Obrabiarka obr = new Obrabiarka(); obr.Operacja(); //Wynik: "Obrabiarka robi coś" Frezarka frez = obr; frez.Operacja(); //Wynik: "Obrabiarka robi coś"
27
Jeszcze lepiej? Refactoring
interface IMaszyna { void Operacja(); } class Frezarka : IMaszyna public virtual void Operacja() Console.WriteLine("Frezarka robi coś"); class Obrabiarka : Frezarka public override void Operacja() Console.WriteLine("Obrabiarka robi coś");
28
Zasada segregacji interfejsów
dzielenie interfejsów na mniejsze grupy, tak by klasa dziedzicząca po nich, nie miała do dyspozycji niepotrzebnych metod nie powinno być jednego dużego interfejsu
29
Zasada odwrócenia zależności
Moduły wysokopoziomowe nie powinny zależeć od modułów niskopoziomowych. Obie grupy modułów powinny zależeć od abstrakcji. moduły wysokopoziomowe – logika biznesowa moduły niskopoziomowe – komunikacją z bazą danych, ftp, API, algorytmy do liczenia Abstrakcje nie powinny zależeć od szczegółowych rozwiązań. To szczegółowe rozwiązania powinny zależeć od abstrakcji.
30
Przykład – źle! class B { public void ZrobCos() { } } class A public void Metoda() B b = new B(); b.ZrobCos();
31
Przykład – dobrze! interface IB { void ZrobCos() { } } class B : IB public void ZrobCos() { } class A public void Metoda() IB b = new B(); b.ZrobCos();
32
Wyjątki i obsługa błędów
Wyjątek - mechanizm kontroli przepływu występujący w językach programowania i służący do obsługi zdarzeń wyjątkowych
33
Blok try catch try { // kod } catch // kod w razie wystąpienia wyjątku
34
try { //kod } catch (Exception e) Console.WriteLine(e.Message);
35
Właściwości klasy System.Exception
Data Dodatkowe informacje na temat źródła wystąpienia wyjątku. HelpLink Umożliwia odczytanie lub ustawienie linka (np. do pomocy) związanego z błędem. Message Komunikat błędu. Source Umożliwia odczytanie lub przypisanie nazwy aplikacji lub obiektu, w którym wystąpił błąd. TargetSite Umożliwia odczytanie metody, w której wystąpił błąd.
36
Celowe wywołanie wyjątku
try { throw new IndexOutOfRangeException(); } catch (Exception e) Console.WriteLine(e.Message);
37
„Najpopularniejsze” wyjątki
StackOverflowException - nieskończona rekurencja OutOfMemoryExcetpion PathTooLongException DirectoryNotFoundException UnauthorizedAccessException FileNotFoundException ArgumentOutOfRangeException ArgumentNullException NullReferenceExcetpion IndexOutOfRangeException DivideByZeroException NotFiniteNumberException OverflowException NotImplementedException
38
Własna klasa na wyjątki – dziedziczy po System.Exception
public class NaszWyjątekException : System.Exception { public NaszWyjątekException (string Message) : base(Message) this.Source = „Nasz własny wyjątek"; this.HelpLink = " }
39
Połykanie kodu – źle! try { // warunek do sprawdzenia } catch(Exception e} { // brak jakiegokolwiek kodu }
40
Wyrzucanie ponowne – źle!
try { // warunek do sprawdzenia } catch(Exception e) { // instrukcje do wykonania. throw e;// źle }
41
Wyrzucanie ponowne – dobrze!
try { // warunek do sprawdzenia } catch(Exception e) { // instrukcje do wykonania. throw;// dobrze! }
Podobne prezentacje
© 2024 SlidePlayer.pl Inc.
All rights reserved.