首页 > 解决方案 > Java:使外部包可访问的类中的包级构造函数。仅允许项目内的某些类访问构造函数

问题描述

我正在开发一个图书馆并试图让一切井井有条。因此,我有嵌套的包结构和一个应该可以访问所有其他类的构造函数的类:

这是我的项目结构:

src
   main
      java
         main
            Main.java
         zoo
            Zoo.java
            animals
               Animal.java
               mammals
                  Dog.java
               fish
                  Salmon.java
               birds
                  Falcon.java

这是我在 main 方法中的代码:

主.java

Zoo zoo = new Zoo(password);
Animal dog = zoo.getDog(name);
Animal salmon = zoo.getSalmon(name);
Animal falcon = zoo.getFalcon(name);

我想阻止用户直接(从zoo包外部)创建动物:

Animal dog = new Dog("Charlie");  //error - constructor isn't public

但是我不确定如何完成它。我可以将所有类放在zoo包中,并使动物构造函数只能在包级别访问。但是,我将不得不牺牲包结构e,我宁愿不这样做。

动物园.java

public class Zoo {
    private String password;

    public Zoo(String password)  {this.password = password;}

    public Dog getDog(String name)  {return new Dog(name);}

    public Salmon getSalmon(String name)  {return new Salmon(name);}

    public Falcon getFalcon(String name)  {return new Falcon(name);}
}

动物.java

public abstract class Animal {
    protected String name;
    public Animal(String name)  {this.name = name;}
}

动物

public class Dog extends Animal {
    public Dog(String name) {super(name);}
}
public class Salmon extends Animal {
     public Salmon(String name) {super(name);}
}
public class Falcon extends Animal {
    public Falcon(String name)  {super(name);}
}

那么可以做些什么来完成上述工作呢?也许它存在一些模式?

标签: javaoopdesign-patterns

解决方案


为了保留包结构并确保用户将使用 Zoo 实例实例化动物,您可能必须在 Zoo 类中使用私有工厂。然而,这似乎是一个非常尴尬的解决方案:

public class Falcon extends Animal {

    protected Falcon() {
    }

    protected static Falcon create() {
        return new Falcon();
    }
}

---

public class Dog extends Animal {

    protected Dog() {
    }

    protected static Dog create() {
        return new Dog();
    }
}


---

public class Zoo {

    public Falcon getFalcon() {
        return new FalconFactory().get();
    }

    public Dog getDog() {
        return new DogFactory().get();
    }

    private static class FalconFactory extends Falcon {
        private Falcon get() {
            return create();
        }
    }

    private static class DogFactory extends Dog {
        private Dog get() {
            return create();
        }
    }
}

我不认为这是一个好的设计,但确实这迫使用户使用 Zoo 实例来创建动物。

当然,用户仍然可以创建自己的工厂,继承自 Falcon 或 Dog。


推荐阅读