... більшість сайтів зазначають, що посередник «додає функціональність» ...
Фасад тільки оголює існуючі функціональні можливості під іншим кутом зору.
Посередник «додає» функціональність , оскільки він поєднує в собі різні існуючі функціональні можливості для створення нового.
Візьмемо такий приклад:
У вас є система реєстрації. За допомогою цієї системи реєстрації ви можете увійти у файл, сокет або базу даних.
Використовуючи шаблон дизайну фасаду, ви зможете "приховати" всі взаємозв'язки від існуючих функціональних можливостей за єдиним "інтерфейсом", який виставляє фасад.
Код клієнта:
Logger logger = new Logger();
logger.initLogger("someLogger");
logger.debug("message");
Реалізація може передбачати взаємодію багатьох об’єктів. Але зрештою функціонал вже існує. Можливо, метод "налагодження" реалізований наступним чином:
Реалізація:
class Logger {
private LoggerImpl internalLogger;
private LoggerManager manager;
public void initLogger( String loggerName ) {
this.internalLogger = manager.getLogger( loggerName );
}
public void debug( String message ) {
this.internalLogger.debug( message );
}
}
Функціонал вже існує. Фасад це лише приховує. У цьому гіпотетичному випадку LoggerManager обробляє створення правильного реєстратора, а LoggerImpl - це приватно-пакувальний об'єкт, який має метод "налагодження". Таким чином, Фасад не додає функціональності, а лише делегує деяким існуючим об’єктам.
З іншого боку, посередник додає нову функціональність, комбінуючи різні об’єкти.
Той самий код клієнта:
Logger logger = new Logger();
logger.initLogger("someLogger");
logger.debug("message");
Реалізація:
class Logger {
private java.io.PrintStream out;
private java.net.Socket client;
private java.sql.Connection dbConnection;
private String loggerName;
public void initLogger( String loggerName ) {
this.loggerName = loggerName;
if ( loggerName == "someLogger" ) {
out = new PrintStream( new File("app.log"));
} else if ( loggerName == "serverLog" ) {
client = new Socket("127.0.0.1", 1234 );
} else if( loggerName == "dblog") {
dbConnection = Class.forName()... .
}
}
public void debug( String message ) {
if ( loggerName == "someLogger" ) {
out.println( message );
} else if ( loggerName == "serverLog" ) {
ObjectOutputStrewam oos =
new ObjectOutputStrewam( client.getOutputStream());
oos.writeObject( message );
} else if( loggerName == "dblog") {
Pstmt pstmt = dbConnection.prepareStatment( LOG_SQL );
pstmt.setParameter(1, message );
pstmt.executeUpdate();
dbConnection.commit();
}
}
}
У цьому коді посередником є той, який містить бізнес-логіку для створення відповідного "каналу" для реєстрації, а також для входу в цей канал. Посередник "створює" функціонал.
Звичайно, є кращі способи реалізувати це за допомогою поліморфізму, але суть тут у тому, щоб показати, як посередник "додає" нову функціональність, поєднуючи існуючу функціональність (у моїй вибірці не дуже сильно шкодував), але уявіть собі посередника, прочитайте з бази даних віддалений хост, куди входити, потім створює клієнта і, нарешті, пише в цей потік друку клієнта повідомлення журналу. Таким чином посередник буде "посередництвом" між різними об'єктами.
Нарешті, фасад - це структурний шаблон, тобто він описує склад об’єктів, тоді як посередник є поведінковим, тобто описує спосіб взаємодії об’єктів.
Сподіваюся, це допоможе.