Как провести рефакторинг повторного кода для создания Intents? - PullRequest
0 голосов
/ 29 февраля 2020

Я в основном работаю с другим языком программирования, но сейчас начинаю заниматься android разработкой, прошло много лет с тех пор, как я в последний раз занимался программированием java, поэтому я сильно отстаю по терминологии. В приложении, над которым я работаю, это блок кода, который выглядит примерно так внутри класса с именем NotificationService

Intent intent;
if (type == "1") {
  intent = new Intent(NotificationService.this, ActivityOne.class);
} else if (type == "6") {
  intent = new Intent(NotificationService.this, ActivityTwo.class);
} else {
  intent = new Intent(NotificationService.this, ActivityThree.class);
}

Этот же блок кода более или менее повторяется в действии

Intent intent;
if (type == "1") {
  intent = new Intent(ListActivity.this, ActivityOne.class);
} else if (type == "6") {
  intent = new Intent(ListActivity.this, ActivityTwo.class);
} else {
  intent = new Intent(ListActivity.this, ActivityThree.class);
}

По мере добавления новых type мне нужно будет поддерживать два списка операторов if / elseif / else, как бы я go реорганизовал это, чтобы я мог повторно использовать те же логи c в двух разных местах (одно - NotificationSerivce, а второе - ListActivity?

Ответы [ 3 ]

0 голосов
/ 29 февраля 2020

Как насчет объявления метода для получения активности от типа.

Class<?> getActivityFromType(int type) {
    if(type == 1) return ActivityOne.class;
    if(type == 2) return ActivityTwo.class;
    ...
    ...
    ...
    return null
}

Таким образом, вам не нужно писать чужие, и вы можете создать новое намерение, подобное следующему:

intent = new Intent(ListActivity.this, getActivityFromType(1));

И код намного чище. Кроме того, вы можете поместить все эти намерения, создающие логики c и коды внутри фабричного класса, так что никакие другие классы не должны знать об этой логике создания намерения. Удачного кодирования!

0 голосов
/ 29 февраля 2020

Если бы вы могли переключиться на Kotlin, закрытые классы могли бы вам очень помочь. Вот пример.

Допустим, у вас есть разные типы. Например, введите 1 и введите 2. А пока давайте подумаем только об этих двух типах. Мы можем использовать запечатанный класс, например:

sealed class MyType {
    class Type1 : MyType()
    class Type2 : MyType()
}

Теперь мы можем определить наши пары активности типа <->, например:

sealed class MyPair(type: MyType, activity: Activity) {

    data class Pair1(val type: MyType.Type1, val activity: Activity1) : MyPair(type, activity)
    data class Pair2(val type: MyType.Type2, val activity: Activity2) : MyPair(type, activity)
}

Мы соединяем MyType с деятельностью. Если нам нужно добавить другой тип, все, что нам нужно сделать, это добавить его в закрытый класс MyType. Если нам нужно сопоставить этот новый тип с определенным действием, мы добавим сопряжение в закрытом классе MyPair.

Чтобы получить тип, теперь мы можем использовать это:

fun getType(type: MyType) : KType? {
    MyPair::class.nestedClasses
        .map { it.memberProperties }
        .filter { it.filter { it.returnType in MyType::class.nestedClasses
            .map { it.createType()}}[0].returnType == type::class.createType() }
        .map {it.filter { it.name == "activity" }}
        .firstOrNull().let {
            it?.first()?.let { return it.returnType }
        }

    return DefaultActivity::class.createType()
}

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

Последнее: вам придется изменить тип переменной типа "тип" с Int на MyType.

0 голосов
/ 29 февраля 2020

Вы можете иметь массив со всеми нужными вам намерениями:

Intent[] intents = {new Intent(), new Intent(), ...};

intent = intents[0];
...