Arkitektur

Læringsmål

Efter denne uge kan du:

Erhvervsrelevans

Der er dybest set ikke nogen systemer der ikke bygger på tre-lags arkitekturen. Der er flere design mønstre end nogen kan kende dem alle, men dem vi har valgt er både meget brugt og nyttige for de fleste systemer. Mange af de systemer I kommer til at bruge på jeres arbejde vil være bygget på brugen af design mønstre, så for at i kan forstå store systemer skal I kunne forstå design mønstre.

Ugeplan

Dette minimodul (denne uge og det meste af uge 13) kommer til at have fokus på at lave endnu et web-system. Denne gang er tanken, at I kommer til at gøre det individuelt. Der skal afleveres en opgave i Google Docs med link til en kørende webapplikation på digital ocean og link til kildekode på github senest onsdag den 28. marts kl. 23:55.

Dag Emne
Mandag Klasseundervisning
Tirsdag Vejledning med tutorer
Onsdag Vejledning for de som ønsker det (primært grønne og gule)
Torsdag Vejledning med tutorer
Fredag Evaluering & vejledning.
Onsdag 28. marts Aflevering af opgave via Moodle. Deadine kl. 23:55

Individuel opgave (Legohus)

Vi er ikke de første…

Det vi lærer her på 2. semester, er vi ikke de første, der har rodet med. Og hvis man ikke vil læse en hel masse, så er der en begynder der på stackoverflow i 2010 stillede dette spørgsmål:

I am designing a simple web based application. I am new to this web based domain.I needed your advice regarding the design patterns like how responsibility should be distributed among Servlets, criteria to make new Servlet, etc.

Vi kan klart anbefale at man læser det første svar.

Design mønstre

Design mønstre er best practice løsninger på ofte forekommende problemer. Et velbeskrevet designmønster har oftest en beskrivelse af hvad det er for et problem det forsøger at løse, hvordan løsningen typisk ser ud, hvilke variationer der er i løsningen, hvilke ulemper brugen af mønsteret har (ofte mere kompleks kode), og andre måder man typisk løser beslægtede problemer.

Resourcer

Der er en god Lynda.com ressource om design mønstre.

Wikipedia har ganske udemærkede artikler om disse designmønstre:

Kasper har lavet en “eksemplarisk” løsning på det klassiske login.

Singleton

Nogle gange kan det være nyttigt at sikre sig at der kun laves en instans af en klasse. Et eksempel kan være at sikre at der kun oprettes en database forbindelse.

Det gøres ved hjælp at følgende lille trick som bygger på static metoder og static felter:

public class Connector {

    private static final String url = "jdbc:mysql://46.101.253.149:3306/useradmin";
    private static final String username = "doorkeeper";
    private static final String password = "bank3*andyouarein";

    private static Connection singleton;

    public static Connection connection() throws ClassNotFoundException, SQLException  {
        if ( singleton == null ) {
            Class.forName( "com.mysql.jdbc.Driver" );
            singleton = DriverManager.getConnection( url, username, password );
        }
        return singleton;
    }
}

Når man udefra vil have fat i en database connection, så kalder man metoden: Connector.connection(). Første gang man kalder metoden er singleton feltet null og man kommer ind i if sætningen og der oprettes en ny forbindelse som så returneres. Næste gang man beder om den, så vil singleton allerede have en værdi, og der oprettes ikke en ny, men den allerede eksisterende forbindelse bliver brugt igen.

Det med at genbruge database connections er vigtigt, og i store systemer har man connections-pools som man så genbruger af. Det ligger uden for vores pensum at kikke på det. Der skal oprettes særlige klasser og metoder der lukker disse forbindelser igen, og dette er koblet til session begrebet på snedig vis. Vi bruger bare singleton, og kan evt. lukke database forbindelsen når der logges ud, men man skal så lige tilføje en metode til at nulstille singleton så næste bruger ikke får en lukket database forbindelse udleveret.

Få afhængigheder og høj sammenhængskraft

Inden for software udvikling vil man gerne at programmerne er “velstrukturerede”. Det er der skrevet meget om, men et helt fundamentalt begreb er at ethvert modul skal have et klart formål, og at det skal være muligt at dette modul skal have så få ydre afhængigheder.

Det betyder f.eks. at en metode kun bør gøre en ting, at en klasse kun skal bruges til at løse en overordent opgave. Og at den kode der inde i en metode skal arbejde på den eneting og ikke andet.

I login eksemplet er det sådan, at Login-kommandoen kun afhænger af det request der kommer ind og facaden mod forretningslaget. Alt koden inde i metoden handler kun om det at håndtere login, og kun den del af login der gælder hvis det går godt (se senere om Exceptions).

Hvis vi kikker på UserMapper, så har hver af de to metoder også en klar opgave, den ene skal logge brugeren ind (i CRUD sammenhæng er det en “read”, hvor vi finder brugeren i databasen), mens den anden metode opretter en ny bruger.

Forskellige former for afhængigheder og sammenhængskraft

Hvis vi kikker på tre klasser - HashMap, Facaden og UserMapper - de to sidste fra dette projekt, og HashMap fra begyndelsen af semesteret. Alle tre klasser har flere metoder (ok, mindst 2).

Generelt om sammenhængskraft og afhængigheder

Ofte snakker man om sammenhængskraft og afhængigheder for moduler. I vores java verden er der tre niveauer af moduler, pakker, klasser og metoder. Begrebet sammenhængskraft og afhængigheder gælder for alle tre niveauer:

Exceptions

I 1997 var der nogle folk på Sun Microsystems (senere købt af Oracle) der lavede et interface der hedder jdbc. Der er mange ting der kan gå galt i forbindelse med database kald, f.eks: rettigheder der ikke er i orden, fejl i forhold til SQL syntaksen og constraints der bliver brudt.

De folk der designede det interface for 20 år siden vidste at sådanne fejl ville komme til at ske. Men de havde ingen mulighed for at vide hvordan du, 20 år senere, ønskede at dit program skal reagere når der er fejl.

Exceptions er en mekanisme der kan bruges til på systematisk måde at dele arbejdet mellem biblioteksprogrammører og applikations programmører.

Dette diagram viser hvordan du kan håndtere en fejl der kommer fra databasen

Brugeren poster en form med data der skal opdateres nede i databasen. Men et eller andet går galt i JDBC laget (hvilket den kode der blev skrevet for 20 år siden opdaget), og der returneres ikke normalt, men kastes in SQLException.

Storage laget skal skjule at der bruges en SQL database for resten af dit system, og derfor skal der ikke slippe SQL exceptions ud af storage layer. Mapperen fanger derfor SQLException. Men storage laget kan ikke kommunikere med brugeren (og kan derfor ikke gøre noget ved problemet). Det kaster derfor en LoginSampleExeption (som er defineret i Logic layer).

Logik laget kan heller ikke gøre noget ved problemet, og sender det derfor exception videre tilbage til servletten.

Servletten fanger exception, og sender brugeren til en fejl-side. Der er forskellige muligheder for at håndtere det anderledes:

Bemærk, hvis man ikke håndterer fejlen, så vil tomcat håndtere det med en fejl 500, og det ser ikke godt ud!

Oprette ny bruger

Når man gerne vil oprette sig som bruger på systemet, så skal man benytte en email der ikke allerede er brugt, og man skal skrive sit password 2 gange for at øge chanchen for at man kan huske det.

Hvordan skal vi checke de to dele?