抽象工厂模式 - 实现它的正确方法

时间:2013-11-14 19:13:09

标签: java design-patterns factory abstract

这是我的代码

public class FactoryPatternDemo {
public static void main(String[]args)
{
    AbstractFactory shapeFactory=new ShapeFactory();

    //tramite la fabbrica di figura geometrica disegno un rettangolo..
    Shape shape1=shapeFactory.getShape("rEcTaNgLe");
    shape1.draw();

    System.out.println();

    //..e un triangolo
    Shape shape2=shapeFactory.getShape("triangle");
    shape2.draw();
}

形状工厂:

public class ShapeFactory extends AbstractFactory{

public ShapeFactory(){

}

@Override
public Shape getShape(String shapeType)
{
    if (shapeType==null)
            return null;
    if (shapeType.equalsIgnoreCase("RECTANGLE"))
            return new Rectangle();
    if (shapeType.equalsIgnoreCase("TRIANGLE"))
            return new Triangle();
    return null;
}

抽象工厂:

public abstract class AbstractFactory {
public abstract Shape getShape(String shapeType);}

摘要产品

public interface Shape {
void draw();}

混凝土产品#1

public class Rectangle implements Shape {

@Override
public void draw() {
    for(int i=0; i<5; i++)
    {
        if(i==0 || i==4)
        {
            for(int j=0; j<10; j++)
            {
                System.out.print("*");
            }
        }
        else
        {
            for(int j=0; j<10; j++)
            {
                if(j==0||j==9)
                    System.out.print("*");
                else
                    System.out.print(" ");
            }
        }
        System.out.print("\n");
    }

}

我的问题是:这是实现抽象工厂模式的正确方法吗?客户端应该只能在FactoryPatternDemo类中看到抽象的东西或接口,但是这行代码:

 AbstractFactory shapeFactory=new ShapeFactory();

显示具体工厂的名称。这是一个错误吗?谢谢你们

1 个答案:

答案 0 :(得分:0)

嗯,我肯定不会使用这个设计!它起泡的原因至少有以下几个原因:

  1. ShapeFactory.getShape()使用一种不是面向对象设计的开关。
  2. ShapeFactory是编译时依赖于所有Shape对象的。
  3. 没有人不能扩展你的图书馆!试着想象一下,的某个人如何控制你的ShapeFactory想要添加一个新形状......不可能!
  4. 我看不出AbstractFactory应该是抽象类而不是接口的任何原因。在我看来,它似乎是C ++的遗产,而不是Java设计。
  5. 了解java.sql.DriverManager.getConnection(connectionString)方法的实现方式。最好的方法是观看源代码。

    非常粗略的想法总结(它隐藏在很多私有方法中)。它或多或少是责任链的实现,尽管没有相关的驱动因素列表。

    DriverManager管理一系列驱动程序。 每个驱动程序必须通过调用其方法DriverManager将自己注册到registerDriver()。 在请求连接时,getConnection(connectionString)方法依次调用传递connectionString的驱动程序。 如果给定的连接字符串在其权限范围内,则每个驱动程序都知道。如果是,则创建连接并返回它。否则,控件将传递给下一个驱动程序。 类比:

    • drivers:your concrete ShapeFactories
    • 连接字符串:形状的类型
    • 连接:形状的实例

    我会尝试这样的事情:

    public class ShapeManager {
        public void registerFactory(ShapeFactory factory) {
            // store the factory to the internal list
        }
        public shape getShape(String shapeType) {
            // go through the list of registered factories until one of them returns non-null
        }
    }
    
    public interface ShapeFactory {
        /**
         * Returns an instance of a shape, if shapeType is supported
         */
        public shape getShape(String shapeType);
    }
    
    public class TriangleFactory implements ShapeFactory {
        public static final String SHAPE_TYPE = "Triangle";
        @Override 
        public shape getShape(String shapeType) {
            if (SHAPE_TYPE.equals(shapeType) {
                return new Triangle();
            }
        }
    }
    
    public class RectangleFactory implements ShapeFactory {
        public static final String SHAPE_TYPE = "Rectangle";
        @Override 
        public shape getShape(String shapeType) {
            if (SHAPE_TYPE.equals(shapeType) {
                return new Triangle();
            }
        }
    }
    
    public class Client {
        ShapeFactory factory;
    
        // This is performed somehow on a global level, maybe by Spring configuration or so
        // However it is *not* part of the ShapeFactory so anyone may add their own shapes,
        // apart from those provided by default by your shape library.
        public void setUp() {
           factory = new ShapeFactory();
           factory.registerFactory(new TriangleFactory());
           factory.registerFactory(new RectangleFactory());
        }
    
        public void use() {
            final Shape triangle = factory.getShape("Triangle");
            final Shape rectangle = factory.getShape("Rectangle");
        }
    }