强制某人仅使用工厂来创建对象

Enforce someone to use only factory for creating objects

我有一个 Shape 接口,并且有 CircleTriangle class 实现了 Shape 接口。可以说方法是 printShape() ,它只打印形状类型。

现在有一个工厂 class 即 ShapeFactory 基于提供 CircleTriangle 对象的工厂设计模式。

现在我想强制大家使用ShapeFactory来创建CircleTriangle的对象。

如果有人不知道 ShapeFactory 存在,那么 he/she 可以使用 new 创建对象而不使用 Shapefacoty。我想要没有人应该创建一个像 Shape shape = new Circle 这样的对象。

我该怎么做?

    // this class is in package scope, nobody can access it outside this package
class ShapeImpl1 implements Shape {

        // default is package scope
        ShapeImpl1() {
        }

        @Override
        public void print() {

        }
    }

    public class ShapeFactory {


        public Shape buildShape() {
            return new ShapeImpl1();
        }
    }

好吧,如果您不希望任何人都可以使用 class,除了您自己的包中的 classes ,然后简单地使那些 classes package-private.

IF 你想禁止 classes 甚至来自与 ShapeFactory 相同的包来使用实现 Shape 的 classes界面,然后跳过第一个示例并转到 UPDATE 引用下方的示例。

看看下面的示例,它展示了包的用法。

package Shapes;

class Circle implements Shape{
//implementation
}

package Shapes; 

class Triangle implements Shape{
//implementation
}

package Shapes;

public class ShapeFactory{

  public static Triangle createTriangle(){
    return new Triangle();
  }

  public static Circle createCircle(){
    return new Circle();
  }
}

package SomeOtherPackage;
import Shapes.ShapeFactory;

public class OtherClass{
  Shape myCircle = ShapeFactory.createCircle();
  Shape myTriangle = ShapeFactory.createTriangle();
}

最后,关于如果用户不知道ShapeFactory存在怎么办?问题。 这就是文档存在的原因。让其他程序员,使用你的API,知道如何使用它!

UPDATE

Even though the above methodology is correct and will provide the functionality that is asked, the below paradigm will demonstrate how to prevent other classes (even from within the same package) to be able to use classes that implement the Shape interface. They will only be able to create other shapes via ShapeFactory().

//ShapeFactory can be public, or package-private. Depends on programmer's needs
public class ShapeFactory {

    //If factory methods are static, then inner classes need to be static too!
    public static Circle createCircle(){
        return new Circle();
    }

    public static Triangle createTriangle(){
        return new Triangle();
    }


    /*Inner classes must  be set to private, to mask their existance
     from all other classes, except ShapeFactory. Static is only needed
     if the factory method that produces an instance of said class, is
     going to be static itself.*/
    static private class Circle implements Shape{
        private Circle(){
            //Circle implementation
        }
    }

    static private class Triangle implements Shape{
        private Triangle(){
            //triangle implementation
        }
    }

    //More inner classes, etc..

}

After ShapeFactory is created as above, Shapes can be instantiated from any class of any other package, (even from the same package as ShapeFactory), ONLY via ShapeFactory.

//An arbitrary class that can belong to any package
public class ArbitraryClass {
    
    public static void main(String[] arguments){
        //creation of Shapes using ShapeFactory
        Shape myCircle = ShapeFactory.createCircle();
        Shape myTriangle = ShapeFactory.createTriangle();
    }
}