问题
I was studying the design patterns and came across Abstract Factory Pattern
which by definition is :
Abstract Factory Pattern says that just define an interface or abstract class for creating families of related (or dependent) objects but without specifying their concrete sub-classes.That means Abstract Factory lets a class returns a factory of classes.
But I am not able to understand it thoroughly. I even went through some examples given in this link and this question, but nothing helped.
Can anyone provide a clear explanation with a simple, real life example of Abstract Factory Pattern
and the cases in which we should use this design pattern.
回答1:
This is the flow of the Abstract factory pattern.Its implemented in java
//create a shape interface and implementer classes 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.");
}
}
//create color interface and its implementers
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.");
}
}
//create abstract factory class that is generally a class that generates the interfaces or in easy language a factory that can manufacture anything you ask of it
public abstract class AbstractFactory {
abstract Color getColor(String color);
abstract Shape getShape(String shape) ;
}
//create shape factory just like you know normal factories manufacture things. This is the factory that manufactures shapes.you just give it the name of the shape you want and it will manufacture it
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;
}
}
//color factory .This is the factory that manufactures colors . you just give it the name of the color you want and it will manufacture it
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;
}
}
//produces factories .Now this class is like an investor who constructs factories . give it the name and it will construct for you the factory that manufactures that.
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;
}
}
//This is the demo class like the dealer who would request an investor to construct a shape factory and this factory can then manufacture rectangles, squares etc.
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();
}
}
回答2:
The key word for abstract factory is the "families". Below is my very simple example.
As you can see, the Boss does not need to know what kind of factory it is, as long as it is a VehichleFacotry. Boss simply invokes Build() and the relative Vehicle is created.
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());
}
}
回答3:
Suppose you are designing a page in which you need to fetch the data from the server(with paging), trigger some analytics events and has customisable views.
Now you want this page to be generic enough to be used by anyone who wishes to use same set of functionalities.
So what could differ?
the Endpoint from where you fetch the data.
Analytics you want to trigger for various events (when user scrolls some views, click on some view, on page load, when user navigates to next page etc)
Different Menu items for different pages.
You can encapsulate what varies and put them into separate classes. Something like this
class MyPage {
IDataFetcher datafetcher;
IAnalyticsHelper analyticsHelper;
IMenuBuilder menuBuilder;
}
Now your MyPage class depends on these classes for the page to be rendered. But if you observe closely these are the family of algorithms which will work together in order to render a page. (A big hint that you could use an abstract factory).
So probably you could change your code to :
public interface IPageAbstractFactory {
IDataFetcher getDatafetcher();
IAnalyticsHelper getAnalyticsHelper();
IMenuBuilder getMenuBuilder();
}
class MyPage {
IPageFactory factory;
}
We just implemented an abstract factory!!! I hope my example is clear.
来源:https://stackoverflow.com/questions/38504837/abstract-factory-pattern-explanation