На самом деле \r\n
для html стороны вывода. С этими символами вы можете просто создать новую строку в html-коде, чтобы сделать его более читабельным:
echo "<html>First line \r\n Second line</html>";
выведет:
<html>First line
Second line</html>
, что при просмотре страницы будет:
First line Second line
Если вы действительно это имели в виду, вам нужно просто исправить одинарную кавычку с помощью цитаты "":
echo "\r\n";
В противном случае, если вы хотите разбить текст, в нашем примере 'Первая строка' и «Вторая строка», вы должны использовать HTML-код: <br />
:
First line<br />Second line
, который будет выводить:
First line
Second line
Также было бы более читабельным, если вы замените весь сценарий с:
echo "$clientid $lastname \r\n";
Использование экземпляра фабрика показывает реальные преимущества в сочетании с внедрением зависимостей.
Итак, в вашем примере вместо:
{ ...
SomeFactory factory = new SomeFactoryImpl();
Set<SomeClass> list = factory.getSomeListOfObjects();
}
у вас будет:
public ThisClass(SomeFactory someFactory) {
this.factory = someFactory;
}
, затем позже ...
{ ...
Set<SomeClass> list = factory.getSomeListOfObjects();
}
Некоторые моменты:
Я полагаю, что статический метод создания объекта является наиболее популярным подходом, но есть также некоторые варианты использования, в которых сначала имеет смысл создать экземпляр фабрики. Например, если вы хотите объединить его с реестром (где должно быть разрешено сосуществование нескольких реестров).
Также, если фабрика полагается на некоторую динамическую контекстную информацию (соединения с базой данных, ...), на мой взгляд, лучше позволить экземпляру фабрики обрабатывать это.
Вот почему я создаю экземпляры объектов фабрики
RedWidgetFactory
, BlueWidgetFactory
. Конфигурация ортогональна типу (-ам) создаваемых объектов IMO, the code you have is indeed a proper specimen of the GoF Abstract Factory pattern, even if its use is not completely optimal. If I recall correctly, the GoF book describes the relationship between factories (SomeFactory, SomeFactoryImpl) and products (SomeClass) but leaves the specifics of instantiating factories open.
If what you have is an internal API that isn't going to be widely used, what you have is probably sufficient. Otherwise, you could:
If going with #1, I personally usually try and model it after JDBC, where:
Driver
would be the abstract factoryConnections
, Statements
etc are productsDriverManager
(not specified in GoF book explicitly) is the utility class that selects a factory for you based on the JDBC URL passed in(In this case, the DriverManager
goes ahead and creates the product for you also, if you use the getConnection(...)
methods, as most do.)
To tie it back to your question, one could arguably use JDBC by calling
new OracleDriver().connect(...)
But as your pointed out, this is sub-optimal, and somewhat defeats the purpose of using the abstract factory pattern.
This problem used to bother me a lot too, until I realized one day that that pattern actually does not explicitly talk about how factories are created.
I hope this answers your question.
Прежде всего, вы забываете основную цель фабричного паттерна. Я открыл книгу банды четырех, и в ней говорится:
«Определите интерфейс для создания objet, но пусть подклассы решают, какой класс создать. Заводской метод позволяет классу отложить создание экземпляра до подклассов. "
Это означает, что на самом деле вы определяете интерфейс, поэтому SomeFactoryImpl
должен фактически реализовывать интерфейс, определенный где-то еще . Это удобно, когда у вас есть много объектов, которые нужно создать, но вы не хотите заботиться о том, какой это тип объекта ... Например, я использовал их для разработки приложения удаленного поворота, в котором клиент загружал через сериализацию определение некоторых классов, которых не было в клиентской виртуальной машине.
Другой пример - создание объекта для конкретного случая в соответствии с вашими потребностями. Например (как указано на странице википедии, относящейся к этому шаблону проектирования) вы можете представить себе фабрику, которая строит объект, а затем другую фабрику для того же типа объекта, но используемую для генерации «поддельных объектов», которые не пройдут какого-либо модульного тестирования.
Однако вы также можете решить вашу конкретную проблему с помощью статических методов, но подумайте о разделении части, которая генерирует элементы, от части, которая использует их в большом проекте. Конечно, тот, кто разрабатывает клиентскую часть, должен просто знать, какой интерфейс фабрики используется, и знать только это, чтобы использовать все объекты, определенные в другой части.
Creation Pattern - это своего рода «средство». шаблон, используемый только для определения пользовательских версий конструкторов, не беспокоясь об использовании стандартного определения (с именем метода, равным имени класса), но в нем нет ничего особенного. Просто другой способ определения объектов ... шаблон создания на самом деле не решает никаких конкретных проблем (за исключением конструкторов с одинаковым числом и типом аргументов).