Java: Фасад

Facade Фасад Facade

Фасад — это структурный паттерн, который предоставляет простой (но урезанный) интерфейс к сложной системе объектов, библиотеке или фреймворку.

Кроме того, что Фасад позволяет снизить общую сложность программы, он также помогает вынести код, зависимый от внешней системы в единственное место.

Подробней о Фасаде

Особенности паттерна в Java

Сложность:

Популярность:

Применимость: Паттерн часто встречается в клиентских приложениях, написанных на Java, которые используют какие-то сложные библиотеки или API.

Примеры Фасадов в стандартных библиотеках Java:

Признаки применения паттерна: Фасад угадывается в классе, который имеет простой интерфейс, но делегирует основную часть работы другим классам. Чаще всего, фасады сами следят за жизненным циклом объектов сложной системы.

Пример: Простой интерфейс к сложной библиотеке видеоконвертации

В этом примере Фасад упрощает работу клиента со сложной библиотекой видеоконвертации.

Фасад предоставляет пользователю лишь один простой метод, скрывая за собой целую систему с видеокодеками, аудиомикшерами и другими не менее сложными объектами.

some_complex_media_library: Сложная библиотека видеоконвертации

some_complex_media_library/VideoFile.java: Класс видеофайла

package refactoring_guru.patterns.facade.example.some_complex_media_library;

public class VideoFile {
    private String name;
    private String codecType;

    public VideoFile(String name) {
        this.name = name;
        this.codecType = name.substring(name.indexOf(".") + 1, name.length());
    }

    public String getCodecType() {
        return codecType;
    }

    public String getName() {
        return name;
    }
}

some_complex_media_library/Codec.java: Интерфейс кодека

package refactoring_guru.patterns.facade.example.some_complex_media_library;

public interface Codec {
}

some_complex_media_library/MPEG4CompressionCodec.java: MPEG4 кодек

package refactoring_guru.patterns.facade.example.some_complex_media_library;

public class MPEG4CompressionCodec implements Codec {
    public String type = "mp4";

}

some_complex_media_library/OggCompressionCodec.java: Ogg кодек

package refactoring_guru.patterns.facade.example.some_complex_media_library;

public class OggCompressionCodec implements Codec {
    public String type = "ogg";
}

some_complex_media_library/CodecFactory.java: Фабрика видеокодеков кодеков

package refactoring_guru.patterns.facade.example.some_complex_media_library;

public class CodecFactory {
    public static Codec extract(VideoFile file) {
        String type = file.getCodecType();
        if (type.equals("mp4")) {
            System.out.println("CodecFactory: extracting mpeg audio...");
            return new MPEG4CompressionCodec();
        }
        else {
            System.out.println("CodecFactory: extracting ogg audio...");
            return new OggCompressionCodec();
        }
    }
}

some_complex_media_library/BitrateReader.java: Bitrate конвертер

package refactoring_guru.patterns.facade.example.some_complex_media_library;

public class BitrateReader {
    public static VideoFile read(VideoFile file, Codec codec) {
        System.out.println("BitrateReader: reading file...");
        return file;
    }

    public static VideoFile convert(VideoFile buffer, Codec codec) {
        System.out.println("BitrateReader: writing file...");
        return buffer;
    }
}

some_complex_media_library/AudioMixer.java: Микширование аудио

package refactoring_guru.patterns.facade.example.some_complex_media_library;

import java.io.File;

public class AudioMixer {
    public static File fix(VideoFile result){
        System.out.println("AudioMixer: fixing audio...");
        return new File("tmp");
    }
}

facade

facade/VideoConversionFacade.java: Фасад библиотеки работы с видео

package refactoring_guru.patterns.facade.example.facade;

import refactoring_guru.patterns.facade.example.some_complex_media_library.*;

import java.io.File;

public class VideoConversionFacade {
    public File convertVideo(String fileName, String format) {
        System.out.println("VideoConversionFacade: conversion started.");
        VideoFile file = new VideoFile(fileName);
        Codec sourceCodec = CodecFactory.extract(file);
        Codec destinationCodec;
        if (format.equals("mp4")) {
            destinationCodec = new OggCompressionCodec();
        } else {
            destinationCodec = new MPEG4CompressionCodec();
        }
        VideoFile buffer = BitrateReader.read(file, sourceCodec);
        VideoFile intermediateResult = BitrateReader.convert(buffer, destinationCodec);
        File result = (new AudioMixer()).fix(intermediateResult);
        System.out.println("VideoConversionFacade: conversion completed.");
        return result;
    }
}

Demo.java: Клиентский код

package refactoring_guru.patterns.facade.example;

import refactoring_guru.patterns.facade.example.facade.VideoConversionFacade;

import java.io.File;

public class Demo {
    public static void main(String[] args) {
        VideoConversionFacade converter = new VideoConversionFacade();
        File mp4Video = converter.convertVideo("youtubevideo.ogg", "mp4");
        // ...
    }
}

OutputDemo.txt: Результат выполнения

VideoConversionFacade: conversion started.
CodecFactory: extracting ogg audio...
BitrateReader: reading file...
BitrateReader: writing file...
AudioMixer: fixing audio...
VideoConversionFacade: conversion completed.