- PVSM.RU - https://www.pvsm.ru -
Совсем недавно у меня состоялся разговор с коллегой по поводу новых языков программирования. После того, как разговор зашел о Kotlin, мой друг обронил фразу «Там нулл нельзя передавать, если не указал, что переменная может быть nullable». Эта фраза сильно озадачила меня — а действительно ли, так важны киллер фичи Котлина в сравнении с уже известными языковыми возможностями Явы? Размышления на этот вопрос вылились в целый комплекс примеров, в рамках которых я хочу показать (в первую очередь самому себе, наверно), зачем же нужны все эти новые языковые возможности.
Самая скучная часть разработки на уже обкатанном языке — рутинные задачи. Например, показ картинок. Абсолютно рядовая задача, которая в любом проекте обрастает рядом условностей. Приведу в пример несколько таких:
Абсолютно бытовые условности, которые поддерживаются многими готовыми библиотеками (например, для андроида это Picasso, Glide, etc.).
Соответственно, для каждой загрузки нужно передавать набор подобных настроек. Желательно, чтобы кушало это поменьше процессорного времени и памяти, была возможность использовать шаблоны и т.д…
В самом базовом виде набор таких данных будет преставлять из себя примерно следующий класс:
public class ImageSets {
Boolean inCircle = false;
Boolean needFit = false;
Size size = null;
int defaultDrawableResource = -1;
}
Если оставить его так, то работа с ним будет выглядеть примерно следующим образом:
void useCase() {
BaseJavaClass some = new BaseJavaClass();
some.inCircle = true;
some.needFit = true;
some.defaultDrawableResource = 0;
some.size = new Size(128, 128);
System.out.println(some.inCircle);
System.out.println(some.needFit);
System.out.println(some.size);
}
static ImageSets pattern(){
BaseJavaClass some = new BaseJavaClass();
some.inCircle = true;
some.needFit = true;
some.defaultDrawableResource = 0;
some.size = new Size(128, 128);
return some;
}
У подобного подхода есть несколько минусов, вот пара тех, которые вызывают у меня всегда большее раздражение:
С первым недугом принято бороться с помощью сеттеров (можно конечно объявить конструктор со всем набором переменных, но если в Java их больше трех, плюс некоторые из них могут быть необязательными, мы точно получим где-то в программе вызовы, похожие на Some(0,0, null, null, null, -1, 5)):
public BaseJavaClass setInCircle(Boolean inCircle) {
this.inCircle = inCircle;
return this;
}
public BaseJavaClass setNeedFit(Boolean needFit) {
this.needFit = needFit;
return this;
}
public BaseJavaClass setSize(Size size) {
this.size = size;
return this;
}
public BaseJavaClass setDefaultDrawableResource(int defaultDrawableResource) {
this.defaultDrawableResource = defaultDrawableResource;
return this;
}
void useCase(){
BaseJavaClass some = new BaseJavaClass()
.setInCircle(true)
.setNeedFit(true)
.setDefaultDrawableResource(0)
.setSize(new Size(128, 128));
}
static BaseJavaClass pattern1() {
return new BaseJavaClass()
.setInCircle(true)
.setNeedFit(true)
.setSize(new Size(128, 128));
}
Что же, допустим. Но что делать со второй проблемой? Обычно для ее решения используют вспомогательный _Bulder класс, вызов которого будет содержать сеттеры, а вызов основного класса — только геттеры:
public class ImageSets {
protected Boolean inCircle = false;
protected Boolean needFit = false;
protected Size size = null;
protected int defaultDrawableResource = -1;
public Boolean getInCircle() {
return inCircle;
}
public Boolean getNeedFit() {
return needFit;
}
public Size getSize() {
return size;
}
public int getDefaultDrawableResource() {
return defaultDrawableResource;
}
public static final ImageSets pattern = new ImageSetsBuilder()
.setInCircle(true)
.setNeedFit(true)
.setDefaultDrawableResource(0)
.setSize( new Size(128, 128));
}
public class ImageSetsBuilder extends ImageSets {
public ImageSetsBuilder setInCircle(Boolean inCircle) {
this.inCircle = inCircle;
return this;
}
public ImageSetsBuilder setNeedFit(Boolean needFit) {
this.needFit = needFit;
return this;
}
public ImageSetsBuilder setSize(Size size) {
this.size = size;
return this;
}
public ImageSetsBuilder setDefaultDrawableResource(int defaultDrawableResource) {
this.defaultDrawableResource = defaultDrawableResource;
return this;
}
}
Существует много других способов, я привел наиболее распространенные способы решения.
Что же стало с нашими данными? Как так вышло, что класс, содержащий в себе всего 4 переменных, разросся до подобных размеров? Что произойдет при добавлении переменных?
Этот же класс, но на языке Kotlin будет выглядеть следующим образом:
class ImageSets(
val inCircle: Boolean = false,
val needFit: Boolean = false,
val size: Pair<Int, Int>? = null,
val defaultDrawableResource: Int = -1)
Все! Можем использовать:
val pattern = ImageSets(
inCircle = true,
needFit = true,
defaultDrawableResource = 0,
size = 128 to 128)
fun useCase(){
val some = ImageSets(
inCircle = true,
needFit = true,
defaultDrawableResource = 0)
print(some.needFit)
}
Написанный на Kotlin пример дает нам следующие преимущества:
В дальнейшем обращение к значениям свойств происходит так же, как и к обычным переменным.
Автор: Денис Александров
Источник [1]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/java/270858
Ссылки в тексте:
[1] Источник: https://habrahabr.ru/post/344864/?utm_source=habrahabr&utm_medium=rss&utm_campaign=344864
Нажмите здесь для печати.