В ситуациях, когда тестируемый класс может быть изменен, и когда желательно избегать манипулирования байтовым кодом, чтобы ускорить работу или свести к минимуму зависимость от третьей стороны, вот мой вопрос о том, как использовать фабрику для извлечения new
операция.
public class TestedClass {
interface PojoFactory { Pojo getNewPojo(); }
private final PojoFactory factory;
/** For use in production - nothing needs to change. */
public TestedClass() {
this.factory = new PojoFactory() {
@Override
public Pojo getNewPojo() {
return new Pojo();
}
};
}
/** For use in testing - provide a pojo factory. */
public TestedClass(PojoFactory factory) {
this.factory = factory;
}
public void doSomething() {
Pojo pojo = this.factory.getNewPojo();
anythingCouldHappen(pojo);
}
}
При этом ваше тестирование, подтверждение и проверка вызовов объекта Pojo просты:
public void testSomething() {
Pojo testPojo = new Pojo();
TestedClass target = new TestedClass(new TestedClass.PojoFactory() {
@Override
public Pojo getNewPojo() {
return testPojo;
}
});
target.doSomething();
assertThat(testPojo.isLifeStillBeautiful(), is(true));
}
Единственный недостаток этого подхода потенциально может возникнуть, если TestClass
имеет несколько конструкторов, которые вам придется дублировать с дополнительным параметром.
По причинам SOLID вы, вероятно, захотите поместить интерфейс PojoFactory в класс Pojo, а также на фабрику.
public class Pojo {
interface PojoFactory { Pojo getNewPojo(); }
public static final PojoFactory productionFactory =
new PojoFactory() {
@Override
public Pojo getNewPojo() {
return new Pojo();
}
};
У нас была подобная проблема в прошлом. И найденный хорошим решением:
Мы испытали то использование гуидов, Вы получаете более или менее универсальное подразделение. И это работало как очарование.
Ссылки, которые могли бы помочь генерировать уникальный идентификатор:
Посмотрите на файловую систему XFS. Он поддерживает неограниченное количество файлов, и Linux поддерживает это. http://oss.sgi.com/projects/xfs/papers/xfs_usenix/index.html
При сохранении файлов, связанных с идентификаторами auto_increment, я использую что-то вроде следующего, которое создает три уровня каталогов, каждый из которых состоит из 1000 каталогов и 100 файлов в каждом каталоге третьего уровня. Это поддерживает ~ 100 миллиардов файлов.
если $ id = 99532455444, то следующее возвращает / 995/324/554/44
function getFileDirectory($id) {
$level1 = ($id / 100000000) % 100000000;
$level2 = (($id - $level1 * 100000000) / 100000) % 100000;
$level3 = (($id - ($level1 * 100000000) - ($level2 * 100000)) / 100) % 1000;
$file = $id - (($level1 * 100000000) + ($level2 * 100000) + ($level3 * 100));
return '/' . sprintf("%03d", $level1)
. '/' . sprintf("%03d", $level2)
. '/' . sprintf("%03d", $level3)
. '/' . $file;
}
Я знаю, что нецелесообразно размещать все в одном каталоге на сервере, поскольку это замедлит доступ к сканированию.
Это предположение.
Я разработал системы, в которых миллионы файлов хранились в одном каталоге, и это прекрасно работало. Это также самая простая в программировании система. Большинство файловых систем сервера поддерживают это без проблем (хотя вам нужно будет проверить, какую из них вы используете).
Я работал над Системой электронного документооборота несколько лет назад, и мы сделали в значительной степени что Gamecat и предложенный wic.
таким образом, присвойте каждому изображению уникальный идентификатор и использование что получить относительный путь к файлу изображения. Мы использовали MOD, подобный тому, какой предложенный wic, но мы позволили 1 024 папки/файла на каждом уровне с 3 уровнями, таким образом, мы могли поддерживать файлы 1G.
Мы сняли изоляцию с расширения из файлов как бы то ни было. Записи DB содержали Тип MIME, таким образом расширение было не нужно.
я не рекомендовал бы хранить полный URL в записи DB, только идентификатор Изображения. При хранении URL, Вы не можете переместить или реструктурировать свое устройство хранения данных, не преобразовывая Ваш DB. Относительный URL был бы в порядке начиная с того способа, которым можно, по крайней мере, переместить репозиторий образов вокруг, но Вы получите больше гибкости, если Вы просто сохраните идентификатор и получите URL.
кроме того, я не рекомендовал бы позволить прямые ссылки Вашим файлам изображений от сети. Вместо этого предоставьте URL программе серверной стороны (например, Сервлет Java), с идентификатором Изображения, предоставляемым в Запросе URL (http://url.com/GetImage?imageID=1234
).
сервлет может использовать тот идентификатор, чтобы искать запись DB, определить Тип MIME, получить фактическое местоположение, проверить на ограничения безопасности, вход, и т.д.
Я обычно просто использую числовой идентификатор базы данных (auto_increment) и затем использую modulu (%) оператор для выяснения, куда поместить файл. Простой и масштабируемый. Например, путь для обработки изображений с идентификатором 12345 мог быть создан как это:
12345 % 100 = 45
12345 % 1000 = 345
Заканчивается в:
/home/joe/images/345/45/12345.png
Или что-то как этот.
при использовании Linux и ext3 и файловой системы необходимо знать, что существуют пределы количеству каталогов и файлов, которые Вы можете иметь в каталоге. Предел 32000 для директоров, таким образом, необходимо всегда стремиться поддержать число на низком уровне директоров.
Вы могли alawys иметь столбец DateTime в таблице и затем хранить их в папках, названных после месяца, года или даже месяца, дня, года изображения, где добавлено к таблице.
Пример
этот путь Вы заканчиваете без более тогда 3 папок глубоко.
Можно проверить stratey, используемый Apple iPod для хранения, это - мультимедийный контент. Существуют папки на одном уровне глубины и файлов с заголовками той же ширины. Я полагаю, что парни Apple инвестировали много времени в тестировании их решения, таким образом, это может принести некоторое мгновенное преимущество Вам.
Используйте иерархию файловой системы. Идентификатор Ваши изображения с помощью чего-то как 001/002/003/004.jpg был бы очень полезен. Разделение является другой историей, все же. Могла быть случайная, базирующаяся дата создания на основе содержимого, и т.д. Действительно зависит от того, каково Ваше приложение.
Можно сохранить изображения в базе данных как блобы ( varbinary для mssql). Тем путем Вы не должны волноваться об устройстве хранения данных или структуре каталогов. Единственный недостаток - то, что Вы не можете легко просмотреть файлы, но это было бы твердо в сбалансированном дереве каталогов так или иначе.
Если изображения, которые Вы обрабатываете, являются цифровыми фотографиями, Вы могли бы использовать данные EXIF для сортировки их, например, датой получения.