У многих рефлексия ассоциируется с раздутым кодом или с не правильным продуманным api.
Под катом несколько полезных примеров, которые покажут положительные стороны рефлексии.
Тренироваться будем наутках сортировках.
Сразу представим себе ситуацию, что сортировок мы хотим изучить много, хотим, чтобы все они работали и были оттестированы.
Однако писать на все алгоритмы тесты нам лень. Поэтому мы протестируем только интерфейс ISort, а все остальные классы, как бы сами собой будут протестированы )
Ну вот и всё, теперь можно официально объявить о победе лени.
Тестирование сортировок теперь будет сведено к созданию таких вот классов
Подобный подход применяется, например, в Spring Data
А так же в других местах, о которых мы даже и не догадываемся.
Под катом несколько полезных примеров, которые покажут положительные стороны рефлексии.
Тренироваться будем на
public interface ISort {
int[] sort(int[] ints);
}
public class MergeSort implements ISort {
// Реализация сортировки
}
public class QuickSort implements ISort {
// Реализация сортировки
}
Сразу представим себе ситуацию, что сортировок мы хотим изучить много, хотим, чтобы все они работали и были оттестированы.
Однако писать на все алгоритмы тесты нам лень. Поэтому мы протестируем только интерфейс ISort, а все остальные классы, как бы сами собой будут протестированы )
// Делаем тест в виде шаблона
public abstract class ISortTest<T extends ISort> {
private Class<T> aClass;
private T sortAlgorithm;
public ISortTest() {
// Получаем тип дженерика заданного в шаблоне
aClass = Optional.of(getClass())
.map(Class::getGenericSuperclass)
.filter(el -> el instanceof ParameterizedType)
.map( el -> (ParameterizedType) el)
.filter(el -> el.getActualTypeArguments().length > 0)
.map(el -> el.getActualTypeArguments()[0])
.filter(el -> el instanceof Class)
.map(el -> (Class<T>) el)
.orElse(null);
}
@BeforeEach
void init() throws IllegalAccessException, InstantiationException {
// Получаем экземпляр конкретной сортировки
sortAlgorithm = aClass.newInstance();
}
@Test
void sortTest() {
assertNotNull(sortAlgorithm);
int n = 10000;
int[] ints = new Random().ints().limit(n).toArray();
int[] sortInts = Arrays.stream(ints)
.sorted()
.toArray();
int[] testSotrInts = sortAlgorithm.sort(ints);
assertArrayEquals(sortInts, testSotrInts);
}
}
Ну вот и всё, теперь можно официально объявить о победе лени.
Тестирование сортировок теперь будет сведено к созданию таких вот классов
class MergeSortTest extends ISortTest<MergeSort> {
// Тут ничего нет
}
class QuickSortTest extends ISortTest<QuickSort> {
// Тут ничего нет
}
Подобный подход применяется, например, в Spring Data
public interface TestRepository extends CrudRepository<MyEntity, Long> {
}
А так же в других местах, о которых мы даже и не догадываемся.