Вот пример кода для сжатия всего каталога (включая подфайлы и подкаталоги), он использует функцию дерева файлов ходьбы Java NIO.
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipCompress {
public static void compress(String dirPath) {
Path sourceDir = Paths.get(dirPath);
String zipFileName = dirPath.concat(".zip");
try {
ZipOutputStream outputStream = new ZipOutputStream(new FileOutputStream(zipFileName));
Files.walkFileTree(sourceDir, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) {
try {
Path targetFile = sourceDir.relativize(file);
outputStream.putNextEntry(new ZipEntry(targetFile.toString()));
byte[] bytes = Files.readAllBytes(file);
outputStream.write(bytes, 0, bytes.length);
outputStream.closeEntry();
} catch (IOException e) {
e.printStackTrace();
}
return FileVisitResult.CONTINUE;
}
});
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Чтобы использовать это, просто вызовите
ZipCompress.compress("target/directoryToCompress");
, и вы получите zip-файл directoryToCompress.zip
задача antcontrib VerifyDesign поможет Вам сделать то, что Вы хотите:
, Например, если существует три пакета в одном исходном дереве
* biz.xsoftware.presentation * biz.xsoftware.business * biz.xsoftware.dataaccess
и естественно представление должно только зависеть от бизнес-пакета, и бизнес должен зависеть от dataaccess. Если Вы определите свой дизайн этот путь, и он нарушен, то сборка перестанет работать, когда verifydesign задачу Ant назовут. Например, если бы я создал класс в biz.xsoftware.presentation, и тот класс зависел от класса в biz.xsoftware.dataaccess, то сборка перестала бы работать. Это гарантирует, что дизайн на самом деле следует за тем, что документируется (до некоторой степени, по крайней мере). Это особенно любезно с автоматизированными сборками
Поэтому, как только Вы решили, как вещи должны быть организованы, можно осуществить требования во время компиляции. Вы также получаете прекрасный-granied контроль, таким образом, можно позволить определенным случаям нарушать эти "правила". Таким образом, можно позволить некоторые циклы.
В зависимости от того, как Вы хотите сделать вещи, Вы могли бы найти, что "utils" пакет имеет смысл.
Для особого прецедента, на который Вы ссылаетесь... Я мог бы сделать что-то вроде этого:
, и Соединение оба высокоуровневые понятия, используемые в NeuralNetowrk, таким образом помещение их всех вместе имеет смысл. Классы Нейрона и Соединения могут относиться друг к другу, в то время как класс Соединения не имеет никакой потребности знать о подклассах Нейрона.
В первую очередь, Вы законно заинтересованы, потому что круговые зависимости между пакетами плохи. Проблемы, которые выходят из него, растут в важности с размером проекта, но никакой причине заняться этой ситуацией вовремя.
необходимо организовать классы путем размещения классов, которые Вы снова используете вместе в том же пакете. Так, если у Вас есть, например, AbstractNeuron, и AbstractConnection, you’d размещают их в тот же пакет. Если у Вас теперь есть реализации, HumanNeuron и HumanConnection, you’d помещают их в тот же пакет (названный, например, *.network.human). Или, у Вас мог бы быть только один тип соединения, например, BaseConnection и много различных Нейронов. Принцип остается таким же. Вы размещаете BaseConnection вместе с BaseNeuron. HumanNeuron в его собственном пакете вместе с HumanSignal и т.д. VirtualNeuron вместе с VirtualSignal и т.д. Вы говорите: “Obviously Соединением не является Нейрон, таким образом, это не должно быть в пакете.. ”. Это не настолько очевидно, ни корректно, чтобы быть точным.
Вы говорите размещение всех нейронов в тот же пакет. Ни один это корректно, если Вы не снова используете все свои реализации вместе. Снова, смотрите на схему, которую я описал выше. Или Ваш проект является настолько маленьким, Вы помещаете все в единственный пакет, или Вы начинаете организовывать пакеты, как описано. Для получения дополнительной информации смотрите на Общий Принцип Повторного использования :
КЛАССЫ В ПАКЕТЕ СНОВА ИСПОЛЬЗУЮТСЯ ВМЕСТЕ. ПРИ МНОГОКРАТНОМ ИСПОЛЬЗОВАНИИ ОДНОГО ИЗ КЛАССОВ В ПАКЕТЕ ВЫ СНОВА ИСПОЛЬЗУЕТЕ ИХ ВСЕХ.
Я не думаю циклические зависимости как те, Вы описываете , имеют , чтобы быть плохим. Пока понятия, которые являются взаимозависимыми, на том же уровне абстракции и касаются тех же частей архитектуры, не может быть необходимо скрыть их друг от друга. Нейроны и Соединения приспосабливают этот счет в моем понимании.
А, распространенный для сокращения таких связей, должен извлечь интерфейсы и возможно даже поместить их в отдельный модуль. Просто организация пакетами в единственном проекте не позволяет Вам скрывать детали реализации достаточно. Общий шаблон, который позволяет Вам действительно скрывать реализации, следующие:
Клиентский Код----> Интерфейсы < Реализация---
В этом шаблоне, Вы скрываете модуль "Реализации" от клиентского кода, что означает, что код в "Клиентском модуле" кода даже не видит код реализации.
вложение пакетов служит нескольким целям: Некоторые проекты могут иметь модель предметной области, которая организована в пакетах. В этом случае пакеты отражают некоторую группировку домена, и ссылки могут пойти/вниз пакеты. Когда дело доходит до вещей как реализация сервисов Ваш предложенный шаблон довольно распространен и хорошая вещь следовать. Чем глубже в иерархии пакета Вы добираетесь, тем более конкретный классу верят, чтобы быть.
О каком размере кода мы говорим? Если у Вас только есть 10-20 классов, Вам, вероятно, не нужно к (и не был должен) сверхорганизовывать Ваш код в пакеты только ради него.
, Поскольку Ваш проект растет, первое различие, которое Вы хотите сделать, состоит в том, чтобы разделить код пользовательского интерфейса от базовой модели данных и логики. Чисто разделение слоев крайне важно, чтобы быть в состоянии сделать надлежащее поблочное тестирование.
, Если Вы испытываете затруднения избавиться от круговых зависимостей, они, вероятно, имеют место, классы являются на самом деле взаимозависимыми, и должны находиться в том же пакете.
Разбирание в уровнях абстракции является, вероятно, одним из самых важных аспектов при разработке полной структуры кода.
, Как Вы обрабатываете эти виды ситуаций?
Круговые зависимости не по сути плохи. На самом деле это может иногда быть случаем "средства исправления, являющегося хуже, чем болезнь": извлечение интерфейса увеличивает уровень сложности Вашего кода и добавляет другой слой косвенности. Это, вероятно, не стоит того для очень простых отношений.