2015-09-05 1 views
1

Я пишу REST API. Я хочу отделить свои классы от аккуратных маленьких папок, но я все еще хочу, чтобы у всех их был доступ к пакетам для eachother.самый идиоматический способ структурирования библиотеки REST на стороне клиента?

Причина в том, что я хочу, чтобы один класс имел только открытый доступ.

Пример:

+---com.mysuper.sdk 
| 
+------ models 
|   |---- Model.java 
+------ controllers 
|   |---- Controller.java 
| 
+---PublicAPI.java 
  1. PublicAPI.java должен быть в состоянии увидеть все модели и контроллеры.
  2. Контроллеры должны уметь видеть модели.
  3. Любой, кто использует мою библиотеку должен быть только в состоянии видеть PublicAPI.java

Что является наиболее идиоматических способ пойти по этому поводу?

+0

* У меня возникает соблазн поместить все файлы в один пакет и предоставить им весь доступ к пакету, за исключением PublicAPI.java, который будет публичным, но это кажется неаккуратным. –

+4

Почему у вас есть только один класс, открытый? Я думаю, что это не очень хороший способ структурировать ваш API. У вас должны быть разные интерфейсы, которые являются общедоступными (где это необходимо), а затем классы реализации, которые имеют доступ к пакетам. Вы можете использовать заводский интерфейс для создания экземпляра или интерфейса поставщика услуг для создания экземпляра реализации для данного публичного интерфейса. –

+0

Это было дано мне таким образом. –

ответ

1

Самый идиоматических способ выразить то, что ваш код, то есть Java конвенции, будет иметь три пакета для вашего кода: com.mysuper.sdk, com.mysuper.sdk.models & com.mysuper.sdk.controllers.

При этом нигде в спецификации языка Java (сентябрь 2015 г.) не требуется, чтобы имена пакетов отражали структуру базовых папок. Возьмем пример ниже:

./src/com/mysuper/sdk/PublicAPI.java

package com.mysuper.sdk; 

// Public class. 
public class PublicAPI { 
    // Main method. 
    public static void main(String... args) { 
     int[] numbers = new int[args.length]; 

     for (int i = 0; i < args.length; i++) { 
      numbers[i] = Integer.parseInt(args[i]); 
     } 

     System.out.println(new Controller().translateNumbers(numbers)); 
    } 
} 

./src/com/mysuper/sdk/controllers/Controller.java

package com.mysuper.sdk; 

// Package protected class. 
class Controller { 
    // Private model. 
    private Model model = new Model(); 

    // Package protected method. 
    String translateNumbers(int... numbers) { 
     String translation = ""; 
     for (int number : numbers) { 
      translation = translation + model.get(number) + " "; 
     } 
     return translation; 
    } 
} 

./src/com/mysuper/sdk/models/Model.java

package com.mysuper.sdk; 

// Package protected class. 
class Model { 
    // Private database. 
    private String[] database = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"}; 

    // Package protected method. 
    String get(int number) { 
     if (number < 0 || number > 9) { 
      throw new NumberFormatException("Number " + number + " is not between 0 and 9."); 
     } else { 
      return database[number]; 
     } 
    } 
} 

Компиляция кода javac не будет бросать какие-либо ошибки синтаксиса, потому что код синтаксически корректен , Попробуйте сами:

javac -d bin ./src/com/mysuper/sdk/PublicAPI.java \ 
./src/com/mysuper/sdk/controllers/Controller.java \ 
./src/com/mysuper/sdk/models/Model.java 

java -cp ./bin com.mysuper.sdk.PublicAPI 0 1 2 3 4 5 6 7 8 9 

Вы должны получить выход по линии:

zero one two three four five six seven eight nine 

Все это уже было сказано, есть несколько причин, почему вы должны придерживаться, чтобы организовать классы в отдельные пакеты.

  1. Большинство IDE будут обрабатывать пакеты, которые не коррелируют с вашей структурой папок как фатальные ошибки компиляции.
  2. Это соглашение, поскольку оно помогает в удобочитаемости кода, направляя других разработчиков в папки, содержащие ваши классы.
  3. Это поможет вам лучше инкапсулировать ваш код для разделения обязанностей ваших модулей кода.

Если вы хотите, чтобы получить подобный результат, а также следующие Java лучшие практики, я призываю вас следовать совету Майкла Аарона Сафьян и ознакомиться с Factory Method pattern абстрагировать реализацию вашего SDK из общедоступного интерфейса.

Как лучше всего реализовать указанный шаблон для вашего проекта, лучше оставить еще один вопрос.

+0

Спасибо, я реализовал это, и он работает. Ваш ответ очень хорошо написан, документирован и прост в понимании, отличная работа. Я согласен с вами в том, что я должен использовать шаблон Factory Method, но я буду использовать это хакерское решение, пока я не получу время, чтобы лучше перестроить SDK. Ты мне очень помог. –

Смежные вопросы