Java: сделать конструктор уровня пакета в классе доступным для внешних пакетов. Разрешить только определенные классы внутри проекта доступ к конструктору - PullRequest
1 голос
/ 11 ноября 2019

Я занимаюсь разработкой библиотеки и стараюсь все организовать. Таким образом, у меня есть вложенная структура пакета и один класс, который должен иметь доступ к конструкторам для всех других классов:

Это моя структура проекта:

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, и я бы предпочел этого не делать.

Zoo.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);}
}

Animal.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);}
}

Итак, что можно сделать для достижения вышеизложенного? Может быть, есть какой-то шаблон для этого?

1 Ответ

1 голос
/ 11 ноября 2019

Чтобы сохранить структуру пакета и убедиться, что пользователь будет создавать экземпляры животных с помощью экземпляра 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 для создания животных.

OfКонечно, пользователь все еще может создать свою собственную Фабрику, которая наследуется от Сокола или Собаки.

...