SOLID är en akronym för fem stycken designprinciper som används vid mjukvaruutveckling. SOLID står för:

Relevanta dokument
JUnit. Ska kompletteras med kodexempel på JUnit. DD2385 Programutvecklingsteknik Några bilder till föreläsning 12 21/5 2012

HT1 2013, FÖRELÄSNING 14 (INFÖR TENTAN)

Static vs Dynamic binding Polymorfism. Objekt-orienterad programmering och design (DIT953) Niklas Broberg, 2018

UML Objektdiagram. Objektorienterad modellering och design (EDAF25) Föreläsning 3. UML Sekvensdiagram. UML Objektdiagram. Agenda

Static vs Dynamic binding Polymorfism. Objekt-orienterad programmering och design Alex Gerdes, 2016

Sammanfattning och Tentamensinfo Objekt-orienterad programmering och design (DIT953) Niklas Broberg, 2018

Kursombud. Objektorienterad modellering och diskreta strukturer / design. Agile? Designprinciper EDAF10 EDA061. Lennart Andersson. Grupper för projekt

Objekt-orienterad programmering och design. DIT953 Niklas Broberg, 2018

Objektorienterad modellering och diskreta strukturer (EDAF10/EDA061)

Objekt-orienterad Programmering och Design. TDA551 Alex Gerdes, HT-2016

Objekt-orienterad Programmering och Design. TDA552 Alex Gerdes, HT-2018

Föreläsning 5. När skall man använda implementationsarv? När skall man använda implementationsarv?

UML Objektdiagram. Objektorienterad modellering och design (EDAF25) Föreläsning 3. UML Sekvensdiagram. UML Objektdiagram. Agenda

Föreläsning 1, vecka 6: Abstraktion genom objektorientering

Modulär design. Objekt-orienterad programmering och design (DIT953) Niklas Broberg / Johannes Åman Pohjola, 2018

Objektorientering/ Klasser

Introduktion. Klasser. TDP004 Objektorienterad Programmering Fö 2 Objektorientering grunder

Separation of Concern. Objekt-orienterad programmering och design (DIT953) Niklas Broberg / Johannes Åman Pohjola, 2018

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 11 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Undantag, Sammanfattning och Tentamensinfo. Objekt-orienterad programmering och design Alex Gerdes, 2016

Principles of subclasses Objekt-orienterad programmering och design (DIT953) Niklas Broberg, 2018

Mjukvarudesign. Designprocessen. Teknisk design. Konceptuell design

Mer OOP. Variation i typ. Medlen repetition. Generiska klasser. Gränssnitt - Interface. Mer om klasser Några exempel UML

Föreläsning 8 - del 2: Objektorienterad programmering - avancerat

Modulär design Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Sänk kostnaderna genom a/ ställa rä/ krav och testa effektivt

Mutability och State. Objekt-orienterad programmering och design (DIT953) Niklas Broberg / Johannes Åman Pohjola, 2018

Analys och design. Objekt. Klass. med hjälp av CRC. Klassdiagram

Viktiga programmeringsbegrepp: Kontrakt

Projekt Rapport. RaidPlanner. Jeanette Karlsson UD10

F8 - Arv. ID1004 Objektorienterad programmering Fredrik Kilander

Principles of subclasses. Objekt-orienterad programmering och design Alex Gerdes, 2018

Seminarierna Instruktioner. Övningarna Viktiga relationer

Objekt, klasser. Tillstånd Signatur Kommunikation Typ. Fält, parametrar och lokala variabler. Konstruktorer Metoder DAVA15

Objektorienterad programmering, allmänt

Viktiga egenskaper hos ett program (Meyer): Objektorienterad programmering, allmänt. Vilka egenskaper vill vi att våra program ska ha?

Objektorienterad programmering

Separation of Concern. Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016 Johannes Åman Pohjola, 2017

PROGRAMMERING. Ämnets syfte. Kurser i ämnet

Vad är. Domändriven design?

Programmering B med Visual C

Generics och polymorfism. Objekt-orienterad programmering och design (DIT953) Niklas Broberg / Johannes Åman Pohjola, 2018

Programutveckling med Java 7.5 p, ht 2007 (D0019N) STUDIEHANDLEDNING - ALLMÄN INFORMATION

Tentamen. 2D4135 vt 2005 Objektorienterad programmering, design och analys med Java Lördagen den 28 maj 2005 kl

Manual för vanliga rapporter i Google Analytics

Syfte : Lära sig objektorienterad programmering Syfte : Lära sig programmering i ett OO-språk vilket?

Generics och polymorfism. Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

SKOLFS. beslutade den XXX 2017.

Computer projekttid. Objektorienterad modellering och diskreta strukturer / design. Rapporter från verkligheten. EDAF10 i HT2

HT1 2015, FÖRELÄSNING 14 (INFÖR TENTAN)

Objekt-orienterad programmering. Klassbegreppet och C++ UML. UMLs fördelar

F9 - Polymorfism. ID1004 Objektorienterad programmering Fredrik Kilander

Abstrakta Klasser 2. Kodning är bara en liten del i programvaruutvecklingen 6% 1% 6% Abstrakta Klasser - deklaration. Programutveckling sker i faser

Introduktion till programmering. Programspråk och paradigmer

TDDC74 FÖRELÄSNING 9 ANDERS MÄRAK LEFFLER IDA/HCS

Priskamp. En prisjämförelsesite Björn Larsson

[SLUTRAPPORT: DRAWPIXLZ (ANDROID-APP)] Slutrapport. Författare: Zlatko Ladan. Program: Utvecklare av Digitala Tjänster 180P

Generic type declarations. Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

"Är en"-relation. "Har en"-relation. Arv. Seminarium 2 Relevanta uppgifter. I exemplet Boll från förra föreläsningen gällde

LEKTIONSTIPS. Lektionstips 2:4. Skribenten vill antingen uttrycka en åsikt för att få andra att reagera, eller

Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 4 Jonas Lindgren, Institutionen för Datavetenskap, LiU

725G61 - Laboration 7 Implementation av ett API. Johan Falkenjack

TDDD78, TDDE30, 729A Typhierarkier del 2 Vad krävs? Hur fungerar det?

Arbeta med databas. Översikt. Lektion 1: Arbeta med Entity Data Models. Arbeta med Entity Data Models. LINQ (Language Integrated Query).

Objektorienterad programmering. Grundläggande begrepp

Webbprogrammering, grundkurs 725G54

Objektorienterad programmering, Java, 5p TDBA63

TENTAMEN. Kurs: Objektorienterad programmeringsmetodik 5DV133 Ansvarig lärare: Anders Broberg. VT-13 Datum: Tid: kl

Avancerade Webbteknologier

Slutrapport YUNSIT.se Portfolio/blogg

Laboration 2: Designmönster

F6 Objektorienterad design. ID1004 Objektorienterad programmering Fredrik Kilander

Design Patterns. Objekt-orienterad programmering och design Alex Gerdes, 2016

Tentamen i EDAF25. 1 juni Skrivtid: Skriv inte med färgpenna enda tillåtna färg är svart/blyerts.

SLUTRAPPORT WEBBPROJEKT 1

Kursplanering Objektorienterad programmering

Objektorienterad programmering

PROGRAMMERING. Ämnets syfte. Kurser i ämnet

Instuderingsuppgifter läsvecka 2

Agila Avtal. avtalsformer som kan fungera. Carina Meurlinger

Laboration 2: Designmönster

UML. Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Inlämningsuppgift : Finn. 2D1418 Språkteknologi. Christoffer Sabel E-post: csabel@kth.se 1

VIDEODAGBOKEN. Individuellt Mjukvaruutvecklingsprojekt. En dagbok i videoform online. Robert Forsgren (rf222ce) UD

Övningsuppgift. Bankkonton. Steg 2. Författare: Mats Loock Kurs: Inledande programmering med C# Kurskod:1DV402

Den mobila användaren sätter traditionella säkerhetssystem ur spel

Vanliga frågor för VoiceXpress

Principer, Patterns och Tekniker. Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Principer, Patterns och Tekniker. Objekt-orienterad programmering och design (DIT953) Niklas Broberg / Johannes Åman Pohjola, 2018

Rune Tennesmed. Oskar Norling 1DV430. Individuellt Mjukvaruutvecklingsprojekt 1DV430 Webbprogrammerare H12 Oskar Norling

Kort repetition. Programmeringsteknik för Bio1 och I1. Vad ska vi lära oss idag? Ett exempel

Datorlaboration :: 1 Problembeskrivning ::

Självhjälpsprogram för ADHD. Del 1 Att hitta din väg

3. När kommer det att vara möjligt? Till sommaren? Vi måste gemensamt se över vad som vill göras, därefter kan vi göra en tidsplan.

Lösningar till tentamen i EDAF25

Omsorgen Användarhandledning

Projekt i programmering 1 (ver 2)... 2 Projektidé... 2 Planering... 2 Genomförande... 2 Testning och buggar... 3 Utvärdering... 3 Planering...

Ajax TruClient. Erfarenheter, tips och trix från Swedbank IT. Christian Gerdes Performance Engineer, LIGHTS IN LINE AB

Fördjupande uppsats i datalogi

Kopiering av objekt i Java

Transkript:

Lektion 32 Övningar Korta punkter Jag vill ha en redovisning från alla grupper där ni går igenom person för person vad personen har ansvarat för och vad och vem personen har parprogrammerat på. Ta även med ickeprogrammeringsrelaterade uppgifter, t.ex. Har fungerat som projektledare, Har ansvarat för dokumentation eller liknande. Om någon av er eller hela gruppen vill lämna in ovanstående individuellt är det ok. Dock vill jag ha ett dokument från gruppen ifall inte hela gruppen väljer att lämna in individuellt. Klart: Torsdag nästa vecka. SOLID SOLID är en akronym för fem stycken designprinciper som används vid mjukvaruutveckling. SOLID står för: Single Responsibility Principle Open/Closed Principle Liskov Substitution Principle Interface Segregation Principle Dependency Inversion Principle Nedan följer en definition av de olika principerna: Single Responsibility Principle: Varje enhet (objekt/metod/etc) skall endast ha ett ansvar. Dvs. istället för att skriva en metod FormatAndRenderHTML som innehåller implementationer för både formattering och rendering så bör metoden brytas isär i FormatHTML och RenderHTML. Ett annat vanligt sätt att uttrycka denna princip är An entity should have one, and only one reason to change. Denna princip medför att enheten kommer bli lättare att underhålla (en ändring av renderingen i exemplet ovan kommer inte påverka formatteringen), koden kommer bli mer lättläst och lättare att testa (Lägg märke till att man för det mesta pratar om klasser/objekt när det gäller denna princip motiveringen fungerar dock lika bra för metoder). Open/Closed Principle: Varje enhet bör vara Öppen för utökningar av funktionalitet, men stängd för modifiering av befintlig funktionalitet. T.ex. Bör du inte ändra implementationen av string-klassen i c# (modifiering), men du kan skriva en extension method för string-klassen om det skulle behövas (utökning). Denna princip gäller dock inte bara klassbibliotek utan även egna implementationer. Om du behöver utökad funktionalitet och åstadkommer det med en extension method så innebär det att den nya funktionaliteten endast kan medföra oönskat beteende på de ställen där extensionmetoden används. Om du istället ändrar en

definition av en befintlig metod i en mogen applikation så innebär det att det finns potentiella oönskade effekter på alla ställen klassen används (Lägg märke till att implementation av interface, arv och wrapper-funktioner är andra sätt att utöka funktionalitet utan att ändra basimplementationen). Denna princip medför att ändringar är mindre troliga att medföra oönskat beteende (t.ex. buggar). Koden kommer troligtvis också bli enklare att underhålla. Liskov Substitution Principle: Ett objekt i ett program bör kunna ersättas med objekt som ärver från detta objekt utan att programmet slutar fungera som tänkt. Dvs. om du implementerar en klass, 3D Chart som ärver utav klassen Chart så bör 3D Chart kunna användas på alla ställen i programmet där Chart används utan att programmet uppvisar oönskat beteende (Namnet på principen kommer f.ö. från namnet på personen som definierade principen). Denna princip medför att användning/implementation av en subtyp (arv) är mindre trolig att medföra oönskat beteende (t.ex. buggar). Koden kommer troligtvis också bli enklare att underhålla. Interface Segregation Principle: Man bör sträva efter att använda många, specifika, interface, snarare än ett interface som täcker flera saker eller allt. Om du t.ex. vill ha objekt som dels skall kunna sparas i en databas och dels skall kunna sparas till filsystemet så bör objektet implementera ett interface för objekt-i-databas-funktionaliteten (t.ex. IEntity som garanterar ett ID) och ett separat interface för objekt-i-filsystemet-funktionaliteten (t.ex. ISerializable som garanterar en metod för att serialisera objektet till filsystemet). Detta gör att ifall vi senare behöver implementera objekt som endast skall sparas till disk så har vi redan ett interface för det och implementationen behöver inte innehålla onödiga funktioner eller liknande för databas-funktionalitet. Denna princip medför att konkreta implementationer hålls rena (inga extra metoder behöver implementeras för att de finns i interfacet). Detta innebär i sin tur att koden blir enklare att underhålla och modifiera. Dependency Inversion Principle: Denna princip innebär att Högnivå-objekt (Förenklat: ett objekt som på något sätt hanterar flera andra objekt t.ex. ett repository) ej skall vara beroende av Lågnivå-objekt. Detta skiljer sig från äldre objektorientering där högnivåobjekt ofta är beroende av konkreta implementationer av lågnivåobjekt. Dependency Injection med interface är ett sätt att följa denna princip. Dvs. om ett UserRepository är implementerat för att hantera objekt som implementerar IEntity snarare än konkreta Userobjekt så följer vi denna princip. Ett annat sätt att uttrycka denna princip som man relativt ofta hör är Depend on abstractions, not concretions/implementation. Denna princip medför att förändringar och återanvändning av kod blir enklare att genomföra. Koden kommer troligtvis också bli enklare att underhålla.

Ursprungligen är de avsedda för objektorienterad programmering, men principerna kan, när man förstår dem, i väldigt stor utsträckning användas även i programspråk som inte har ett starkt stöd för objektorientering. Det skall också nämnas att man väldigt ofta använder SOLID som ett verktyg för analys inför refactoring. Personligen tycker jag inte det är så viktigt att lära sig exakt vad akronymen står för, det viktiga är att förstå anledningarna till att principerna används och att man kan applicera dessa tankesätt på sina implementationer (Om akronymen hjälper dig att komma ihåg principerna så är det ju dock bra ;) SOLID som helhet kan ta lite tid att få fullständig förståelse för (Se nästa stycke för en delförklaring till detta). Det kan därför vara bra att med jämna mellanrum fördjupa sig/repetera dessa principer. De är tänkta att appliceras på eller åtminstone övervägas för allt du implementerar, dvs. det är inte principer som är tänkta att plockas fram någon gång då och då eller för väldigt specifika ändamål. Lägg märke till att dessa principer i väldigt stor utsträckning syftar till förenklat underhåll av källkod (Detta är dock inte det enda syftet med dessa principer som ni kan utläsa ovan). Fördelarna med SOLID är därför ibland inte direkt uppenbara vid en implementation från scratch. Detta gör inte principerna mindre viktiga, som tidigare nämnt är underhåll av källkod normalt sett den överlägset mest kostsamma och tidskrävande delen av utveckling. Övningar Utgångspunkten för övningarna är v0.0 av Lektion32 repot. S Single Responsibility Principle (SRP) 1. Titta på klassen Models/Entities/User.cs Denna klass bryter mot SRP, då den har flera olika ansvarsområden. Vilka ansvarsområden har klassen? 2. Hur gör vi refactoring för att se till att klassen följer SRP? O Open/Closed Principle (OCP) 3. Ponera att Repository-klassen är testad, släppt till produktionsmiljö och anses stabil. Det har kommit in ett nytt krav att en metod, FindUserByEmail(string email) måste implementeras. Att implementera denna metod direkt i Repository-klassen hade brutit mot OCP. Finns det några andra anledningar till att det är en dålig idé att implementera denna metod direkt i Repository-klassen? 4. Hur implementerar vi denna metod samtidigt som vi följer OCP? (Tips: Låt en ny klass, UserRepository ärva från Repository<User> och implementera ett Interface, IUserRepository. Vad bör IUserRepository innehålla i det är fallet? Vad är det vi vill implementera?)

L Liskov Substitution Principle (LSP) Exempel för LSP blir lätt väldigt förenklade, till den grad att det är svårt att se någon riktig nytta med det (Se: A typical violation under http://en.wikipedia.org/wiki/liskov_substitution_principle ), eller så blir exemplen så avancerade att de är svåra att tränga in i. Vi använder här uppgift 3 + 4 för att exemplifiera LSP. 5. Antag att vi innan vi implementerade UserRepository använde oss av Repository<User> på flera ställen i källkoden. Vad hade hänt om vi ersatt alla förekomster av Repository<User> med UserRepository? Hade detta lett till några oönskade beteenden i programmet? Har detta några fördelar? Följer vi LSP? 6. Hur hade vi kunnat bryta mot LSP i vår implementation av UserRepository? I Interface Segregation Principle (ISP) Under Models/ExportableDataSet ligger PageHitStatistics.cs och UserStatistics.cs. Tanken är att dessa klasser skall representera dataset som är underlag för olika typer av statistik för vår sida. Denna statistik skall kunna tas ut i olika format, t.ex. som PDF, Excel-rapport eller som ren text. Statistiken innehåller olika typer av objekt och har olika komplexitet, vilket gör att det inte är lämpligt att exportera samtliga typer av dataset till samtliga typer av rapporter/filtyper. I detta fallet så antar vi att UserStatistics är väldigt komplex och ej lämpligt att ta ut i något annat format än Excel, medans PageHitStatistics är ganska enkel och lämplig att ta ut i graf-form, antingen som en bild eller PDF. När implementationen gjordes så bestämdes det att alla implementationer skall ske mot interface (IExportableSet.cs) för att göra det enkelt att senare utöka antalet rapporter. Förutom metoder för att exportera till Excel, Image och PDF så lades det även till metoder för att exportera till SQL, Text och CSV för att framtidssäkra applikationen. I PageHitStatistics.cs och UserStatistics.cs representerar metoder som är implementerade med new NotImplementedException(); exporter som ej skall vara möjligt att göra för det aktuella datasetet. Övriga metoder representerar fullständiga implementationer. 7. På vilket sätt bryter denna implementation mot ISP? Vilka problem innebär detta? 8. Hur kan vi göra refactoring av denna implementation för att följa ISP? ( int COUNT() - metoden är tänkt att vara implementerad för samtliga implementationer av dessa statistikset). 9. Är framtidssäkringen i form av abstrakta metoder för export till SQL, Text och CSV en bra idé? OBS! Lägg märke till att Implementationerna under ExportableSet potentiellt bryter mot SRP (Detta beror lite på hur den faktiska implementationen ser ut men spontant ser det ut som att klasserna både ansvarar för att representera data och exportera data). En lösning på detta (det finns fler) hade t.ex. kunnat vara att ta bort alla export-metoder både ur interfacen och klasserna i Exportable Dataset.

Vi bygger sedan en ny klass StatisticsExporter som innehåller ett antal statiska metoder för de olika typerna av exporter vi har. T.ex. StatisticsExporter.ExportToPDF(IPDFExportable statisticstoexport) Där de ExportableDataSet som skall kunna exporteras till PDF implementerar interfacet IPDFExportable. Man hade också kunna tänka sig något i stil med StatisticsExporter.Export(ExportStrategy.PDF, statisticstoexport) för en något mer dynamisk lösning. Jag ville dock hålla exemplet så enkelt som möjligt i förevisningssyfte, så jag har bortsett från att vi bryter mot SRP här. D Dependency Inversion Principle (DIP) DIP innebär helt enkelt i praktiken att klasser inte bör vara beroende på konkreta implementationer av andra klasser, utan istället av Interface. Vi har tidigare i kursen sett hur denna princip kan användas för att snabbt ändra vilken implementation av repository man vill använda (DB- eller testimplementation) m.h.a. Dependency Injection, Interface och Ninject. 10. Förklara på vilket sätt en Ninject-binding av Repository använder sig av DIP (Du kan titta på NinjectControllerFactory.AddBindings + Konstruktorn i HomeController för ett exempel på detta. Hur hade en liknande implementation, som ej använder Ninject och inte följer DIP sett ut? (Tips: den privata variabeln i HomeController hade varit en konkretimplementation ej en interface-variabel). 11. Om du hade implementerat ett TestRepository som implementerar interfacet IRepository och velat använda denna implementation istället vad hade du behövt ändra för att detta repository skall användas av samtliga Controllers? (Tips: Det hade räckt att ändra en rad i NinjectControllerFactory.AddBindings-metoden) Länkar/Vidare läsning: Om du utgår från Wikipedia-sidan ( http://en.wikipedia.org/wiki/solid ) så kan du fördjupa dig något, men framförallt hitta vidare länkar och lästips om samtliga principer i SOLID. Vidare kan det vara intressant att läsa artiklar/böcker av Robert C. Martin. Det var Robert som myntade akronymet SOLID (även om han nödvändigtvis inte uppfann alla del-principer). Robert (eller Uncle Bob) har väldigt mycket att säga om SOLID, Software Craftmanship, agila metoder, etc. Robert C. Martin har varit väldigt tongivande för stora delar av den agila rörelsen och var även en av de som lanserade den agila rörelsen iom. Manifesto for Agile Software Development 2001. Man skall dock vara medveten om att han ofta är extremt kompromisslös och fast i sina principer Personligen gillar jag detta eftersom det tvingar mig att värdera/överväga det han säger, men det finns naturligtvis varierande åsikter kring detta.