Шаблон фасада, это нормально?
У меня есть два сервера, к которым я буду подключаться с одного клиента. Для каждого сервера я буду использовать ftp "put" и "rm".
Должен ли я построить один фасад и иметь такой интерфейс:
void putFileOnServer1(String file)
void putFileOnServer2(String file)
void removeFromServer1(String file)
void removeFromServer2(String file)
И должен ли фасад обрабатывать все соединения и разъединения? Если да, то должен ли он использовать фабрику для этого?
3 ответа
У вас есть два метода, PutFileOnServer и RemoveFromServer. Какой сервер вы устанавливаете или удаляете, должен быть частью абстракции.
У ftp-серверов разные интерфейсы? Или они все понимают один и тот же набор команд, которые вы хотите использовать уже?
Если так, то просто создайте
FtpServer
класс, который принимает информацию о соединении. И создатьFtpClient
класс, который принимает несколько серверов, которые вы можете выбрать по некоторому ключу, например. (По крайней мере, это, в некоторой степени, вероятно, будет то, что я бы сделал).class FtpClient { public function addServer( FtpServer $server, $key ); public function selectServer( $key ); public function putFileOnServer( $file ); public function removeFileFromServer( $file ); }
Если нет, и у вас уже есть класс для каждой отдельной реализации, который отличается по своим интерфейсам, например:
class FtpServerFoo { public function selectFile( $file ); public function removeSelectedFile(); } class FtpServerBar { public function removeFile( $file ); }
... вы должны посмотреть на шаблон адаптера:
abstract class FtpServer { abstract public function putFile( $file ); abstract public function removeFile( $file ); } class FtpServerAdapterFoo extends FtpServer { public function __construct( FtpServerFoo $server ) { } public function removeFile( $file ) { $this->server->selectFile( $file ); $this->server->removeSelectedFile(); } } class FtpServerAdapterBar extends FtpServer { public function __construct( FtpServerBar $server ) { } public function removeFile( $file ) { $this->server->removeFile( $file ); } } $cilent = new FtpClient(); $client->addServer( new FtpServerAdapterFoo( new FtpServerFoo() ), 0 ); $client->addServer( new FtpServerAdapterBar( new FtpServerBar() ), 1 ); $client->selectServer( 0 ); $client->putFileOnServer( $file ); $client->selectServer( 1 ); $client->removeFileFromServer( $someOtherfile );
Если у вас пока нет отдельных классов для разных FTP-серверов, вы можете просто реализовать один и тот же интерфейс (или наследовать абстрактный класс) для каждой реализации ftp-сервера и использовать тот же тип класса FtpClient, что и выше.
Хотя, на самом деле, здесь не совсем фасадный рисунок.
Обычно вы используете фасады для уменьшения сложности объектов разных типов. В этом случае, однако, кажется, что вы хотите использовать только один функциональный "тип", "FTPServer". Таким образом, по большей части у вас должно быть два экземпляра этого типа, и этот тип будет иметь методы "put" и "remove".
Когда вы добавляете ненужные функциональные точки, вы фактически увеличиваете сложность обслуживания. Например, если вам нужно добавить новый параметр в ваши функции (может быть, ограничения доступа или что-то еще), вы должны не только изменить для каждого места использования, но теперь необходимо добавить в каждый метод фасада. Абстракция должна уменьшать этот тип связи, а не увеличивать ее.