Аннотация Фабрика Шаблон Объяснение
Я изучал шаблоны проектирования и наткнулся на Abstract Factory Pattern
который по определению:
Abstract Factory Pattern говорит, что просто определите интерфейс или абстрактный класс для создания семейств связанных (или зависимых) объектов, но без указания их конкретных подклассов. Это означает, что Abstract Factory позволяет классу возвращать фабрику классов.
Но я не в состоянии понять это полностью. Я даже просмотрел несколько примеров, приведенных в этой ссылке и в этом вопросе, но ничего не помогло.
Может ли кто-нибудь дать четкое объяснение с простым, реальным примером Abstract Factory Pattern
и случаи, в которых мы должны использовать этот шаблон проектирования.
3 ответа
Это поток абстрактного фабричного шаблона. Он реализован в Java
// создаем интерфейс shape и классы реализатора shape
public interface Shape {
void draw();
}
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
// создаем цветной интерфейс и его реализации
public interface Color {
void fill();
}
public class Red implements Color {
@Override
public void fill() {
System.out.println("Inside Red::fill() method.");
}
}
public class Blue implements Color {
@Override
public void fill() {
System.out.println("Inside Blue::fill() method.");
}
}
// создаем абстрактный класс фабрики, который обычно является классом, который генерирует интерфейсы, или простым языком фабрику, которая может производить все, что вы просите об этом
public abstract class AbstractFactory {
abstract Color getColor(String color);
abstract Shape getShape(String shape) ;
}
// создать фабрику форм, как вы знаете, обычные фабрики производят вещи. Это фабрика, которая производит фигуры. Вы просто даете ей имя нужной вам фигуры, и она будет ее производить.
public class ShapeFactory extends AbstractFactory {
@Override
public Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
}else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
@Override
Color getColor(String color) {
return null;
}
}
// фабрика цветов. Это фабрика, производящая цвета. вы просто даете ему название цвета, который вы хотите, и он будет производить его
public class ColorFactory extends AbstractFactory {
@Override
public Shape getShape(String shapeType){
return null;
}
@Override
Color getColor(String color) {
if(color == null){
return null;
}
if(color.equalsIgnoreCase("RED")){
return new Red();
}else if(color.equalsIgnoreCase("BLUE")){
return new Blue();
}
return null;
}
}
// производит фабрики. Теперь этот класс похож на инвестора, который строит фабрики. дайте ему имя, и он построит для вас фабрику, которая производит это.
public class FactoryProducer {
public static AbstractFactory getFactory(String choice){
if(choice.equalsIgnoreCase("SHAPE")){
return new ShapeFactory();
}else if(choice.equalsIgnoreCase("COLOR")){
return new ColorFactory();
}
return null;
}
}
// Это демонстрационный класс, подобный дилеру, который попросил бы инвестора построить фабрику фигур, и эта фабрика может затем производить прямоугольники, квадраты и т. Д.
public class AbstractFactoryPatternDemo {
public static void main(String[] args) {
//get shape factory
AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
//get an object of Shape Rectangle
Shape shape2 = shapeFactory.getShape("RECTANGLE");
//call draw method of Shape Rectangle
shape2.draw();
//get an object of Shape Square
Shape shape3 = shapeFactory.getShape("SQUARE");
//call draw method of Shape Square
shape3.draw();
//get color factory
AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
//get an object of Color Red
Color color1 = colorFactory.getColor("RED");
//call fill method of Red
color1.fill();
//get an object of Color Blue
Color color3 = colorFactory.getColor("BLUE");
//call fill method of Color Blue
color3.fill();
}
}
Предположим, вы разрабатываете страницу, на которой вам нужно получить данные с сервера (с подкачкой страниц), вызвать некоторые события аналитики и иметь настраиваемые представления.
Теперь вы хотите, чтобы эта страница была достаточно общей, чтобы ее могли использовать все, кто желает использовать тот же набор функций.
Так что может отличаться?
Конечная точка, откуда вы выбираете данные.
Аналитика, которую вы хотите активировать для различных событий (когда пользователь прокручивает некоторые виды, нажимает на некоторые, при загрузке страницы, когда пользователь переходит на следующую страницу и т. Д.)
Различные пункты меню для разных страниц.
Вы можете инкапсулировать то, что меняется, и поместить их в отдельные классы. Что-то вроде этого
class MyPage {
IDataFetcher datafetcher;
IAnalyticsHelper analyticsHelper;
IMenuBuilder menuBuilder;
}
Теперь ваш класс MyPage зависит от этих классов для отображаемой страницы. Но если вы внимательно посмотрите, это семейство алгоритмов, которые будут работать вместе, чтобы отобразить страницу. (Большой намек на то, что вы могли бы использовать абстрактную фабрику).
Так что, вероятно, вы могли бы изменить свой код на:
public interface IPageAbstractFactory {
IDataFetcher getDatafetcher();
IAnalyticsHelper getAnalyticsHelper();
IMenuBuilder getMenuBuilder();
}
class MyPage {
IPageFactory factory;
}
Мы только что реализовали абстрактную фабрику!!! Надеюсь, мой пример понятен.
Ключевое слово для абстрактной фабрики - "семьи". Ниже приведен мой очень простой пример.
Как видите, Босс не должен знать, что это за фабрика, если это VehichleFacotry. Босс просто вызывает Build(), и создается относительная машина.
abstract class Vehicle { }
class Car : Vehicle { }
class Bus : Vehicle { }
abstract class VehicleFactory
{
abstract Vehicle Build();
}
class CarVehicleFactory : VehicleFacory
{
Vehicle Build()
{
return new Car();
}
}
class BusVehicleFactory : VehicleFacory
{
Vehicle Build()
{
return new Bus();
}
}
public class Boss
{
public void Order(VehicleFactory factory)
{
var vehicle = factory.Build();
//do something else ...
}
}
public class Foo
{
public void Bar()
{
var boss = new Boss();
boss.Order(new CarVehicleFactory());
boss.Order(new BusVehicleFactory());
}
}