skip to main content

Design Patterns: Facade


« Terug naar Software Engineering Skills
» Naar de labo opgave

“Facade” - Design Pattern

Begeleidende screencast:

Doelstelling

Dive Into Design Patterns: Facade

Voorbeeld

1. Opzet

Stel dat we gegevens van de klant moeten versturen naar een overheidsinstantie. Die instantie beschikt jammer genoeg niet over voldoende budgetten om ook een cutting-edge server interface en implementatie aan te bieden. Het komt er op neer dat we verplicht zijn om tekst bestanden op een FTP server te plaatsen.

class ClientFtpSender {
    public void upload(Client client) {
        // create ftp connection, upload, ...
    }
}

Deze code gebruiken we als de gebruiker op een knop genaamd export klikt:

class ClientHTTPHandler {
    private ClientRepository clientRepository;
    public HTTPResponse onExport(int clientId) {
        Client client = clientRepository.getById(clientId);
        new ClientFtpSender().upload(client);
        return HTTPResponse.success();  // 200 OK
    }
}
graph LR; A[HTTP Handler] B[FTP Sender] A --> B

2. Probleemstelling

We verkopen onze software aan een andere partij, die niet alleen met de overheid wenst te communiceren, maar ook met een derde instantie. Deze instantie biedt ons de mogelijkheid aan om de klant in de vorm van XML met een POST HTTPS call op te sturen. Onze ClientFTPSender is dus niet meer genoeg:

class ClientPOSTSender {
    public void upload(Client client) {
        // secure HTTPS, encode client in XML, post...
    }
}

Deze complexe stukjes software, de POST en FTP senders, willen we niet langer rechtstreeks aanspreken in de HTTP handler. Het is zo dat afhankelijk van een bepaalde instelling, het ene of het andere gebruikt kan worden.

3. Oplossing

We hebben dus een facade nodig, die de juiste delegaties voor ons doorvoert, zoals in het volgende schema:

graph LR; A[HTTP Handler] POST[POST Sender] FTP[FTP Sender] F{Facade} A --> F F -.-> POST F -.-> FTP

Waarbij de Facade een klasse is die de details “wegstopt” voor onze HTTP handler:

class UploadClientFacade {
    public void upload(Client client) {
        if(settings.isPOST()) {
            new ClientPOSTSender().upload(client);
        } else if(settings.isFTP()) {
            new ClientFtpSender().upload(client);
        } else {
            throw new UnsupportedOperationException("settings?");
        }
    }
}

Eigenschappen van dit patroon

Labo oefeningen

Via Github Classroom.

Opgave 1

We modelleren een dierentuin, waarvan een be.kuleuven.ses.facade.animals.Chicken een gegeven klasse is. Elk dier willen we voederen met de feed() methode. Let op! Sommige dieren vereisten veel meer aandracht (lees: complexiteit), die we willen wegwerken met het introduceren van een Facade.

Voeg klasses be.kuleuven.ses.facade.animals.Cow en Cat toe, geef deze ook eten, en verberg dan het voederen in een aparte interface.

Opgave 2

sessy library:

  1. identificeer waar jij denkt dat een facade nodig zou kunnen zijn. Waar moet logica worden afgeschermd?
  2. Pas het patroon toe waar jij denkt dat het nodig is.

Denkvragen