Skip to main content
added 68 characters in body
Source Link
Mario Ishac
  • 977
  • 6
  • 15

Assuming Update#getMessage() is of type Message and Update#getCallbackQuery() is of type CallbackQuery:

You can make a function getUpdateAttribute that receives higher-order functions as handlers for the situation where your update has a message or callback query as follows.

private static <T> T getUpdateAttribute(Update update,
                                        Function<Message, T> messageFunc,
                                        Function<CallbackQuery, T> callbackQueryFunc) {
    if (updateHasMessage(update)) {
        return messageFunc.apply(update.getMessage());
    }
    if (updateHasCallbackQuery(update)) {
        return callbackQueryFunc.apply(update.getCallbackQuery());
    }

    return null;
}

I simplified the if/else code flow to take advantage of early returns. getUpdateAttribute is also generic over T because your attributes can be various types, like Integer and String. Finally, I made it private so your public attribute fetchers are the only interface exposed. Those attribute fetchers then become:

public static Long getChatId(Update update) {
    return getUpdateAttribute(
        update,
        Message::getChatId,
        callbackQuery -> callbackQuery.getMessage().getChatId()
    );
}

public static String getUserName(Update update) {
    return getUpdateAttribute(
        update,
        message -> message.getFrom().getUserName(),
        callbackQuery -> callbackQuery.getFrom().getUserName()
    );
}

public static String getInputUserData(Update update) {
    return getUpdateAttribute(
        update,
        Message::getText,
        CallbackQuery::getData
    );
}

public static Integer getMessageId(Update update) {
    return getUpdateAttribute(
        update,
        Message::getMessageId,
        callbackQuery -> callbackQuery.getMessage().getMessageId()
    );
}

Apart from this de-duplication, there is something else you can potentially improve. I'm not familiar with the Telegram API, but if it is possible that a message may have neither a message nor a callback query, then returning null seems like a valid response, in which case you may want to return Optional<T> from getUpdateAttribute (and all the other attribute fetchers), as that would signal your intent better.

Assuming Update#getMessage() is of type Message and Update#getCallbackQuery() is of type CallbackQuery:

You can make a function getUpdateAttribute that receives higher-order functions as handlers for the situation where your update has a message or callback query as follows.

private static <T> T getUpdateAttribute(Update update,
                                        Function<Message, T> messageFunc,
                                        Function<CallbackQuery, T> callbackQueryFunc) {
    if (updateHasMessage(update)) {
        return messageFunc.apply(update.getMessage());
    }
    if (updateHasCallbackQuery(update)) {
        return callbackQueryFunc.apply(update.getCallbackQuery());
    }

    return null;
}

I simplified the if/else code flow to take advantage of early returns. getUpdateAttribute is also generic over T because your attributes can be various types, like Integer and String. Finally, I made it private so your public attribute fetchers are the only interface exposed. Those attribute fetchers then become:

public static Long getChatId(Update update) {
    return getUpdateAttribute(
        Message::getChatId,
        callbackQuery -> callbackQuery.getMessage().getChatId()
    );
}

public static String getUserName(Update update) {
    return getUpdateAttribute(
        message -> message.getFrom().getUserName(),
        callbackQuery -> callbackQuery.getFrom().getUserName()
    );
}

public static String getInputUserData(Update update) {
    return getUpdateAttribute(
        Message::getText,
        CallbackQuery::getData
    );
}

public static Integer getMessageId(Update update) {
    return getUpdateAttribute(
        Message::getMessageId,
        callbackQuery -> callbackQuery.getMessage().getMessageId()
    );
}

Apart from this de-duplication, there is something else you can potentially improve. I'm not familiar with the Telegram API, but if it is possible that a message may have neither a message nor a callback query, then returning null seems like a valid response, in which case you may want to return Optional<T> from getUpdateAttribute (and all the other attribute fetchers), as that would signal your intent better.

Assuming Update#getMessage() is of type Message and Update#getCallbackQuery() is of type CallbackQuery:

You can make a function getUpdateAttribute that receives higher-order functions as handlers for the situation where your update has a message or callback query as follows.

private static <T> T getUpdateAttribute(Update update,
                                        Function<Message, T> messageFunc,
                                        Function<CallbackQuery, T> callbackQueryFunc) {
    if (updateHasMessage(update)) {
        return messageFunc.apply(update.getMessage());
    }
    if (updateHasCallbackQuery(update)) {
        return callbackQueryFunc.apply(update.getCallbackQuery());
    }

    return null;
}

I simplified the if/else code flow to take advantage of early returns. getUpdateAttribute is also generic over T because your attributes can be various types, like Integer and String. Finally, I made it private so your public attribute fetchers are the only interface exposed. Those attribute fetchers then become:

public static Long getChatId(Update update) {
    return getUpdateAttribute(
        update,
        Message::getChatId,
        callbackQuery -> callbackQuery.getMessage().getChatId()
    );
}

public static String getUserName(Update update) {
    return getUpdateAttribute(
        update,
        message -> message.getFrom().getUserName(),
        callbackQuery -> callbackQuery.getFrom().getUserName()
    );
}

public static String getInputUserData(Update update) {
    return getUpdateAttribute(
        update,
        Message::getText,
        CallbackQuery::getData
    );
}

public static Integer getMessageId(Update update) {
    return getUpdateAttribute(
        update,
        Message::getMessageId,
        callbackQuery -> callbackQuery.getMessage().getMessageId()
    );
}

Apart from this de-duplication, there is something else you can potentially improve. I'm not familiar with the Telegram API, but if it is possible that a message may have neither a message nor a callback query, then returning null seems like a valid response, in which case you may want to return Optional<T> from getUpdateAttribute (and all the other attribute fetchers), as that would signal your intent better.

added 423 characters in body
Source Link
Mario Ishac
  • 977
  • 6
  • 15

Assuming Update#getMessage() is of type Message and Update#getCallbackQuery() is of type CallbackQuery:

You can make a function getUpdateAttribute that receives higher-order functions as handlers for the situation where your update has a message or callback query as follows.

private static <T> T getUpdateAttribute(Update update,
                                        Function<Message, T> messageFunc,
                                        Function<CallbackQuery, T> callbackQueryFunc) {
    if (updateHasMessage(update)) {
        return messageFunc.apply(update.getMessage());
    }
    else if (updateHasCallbackQuery(update)) {
        return callbackQueryFunc.apply(update.getCallbackQuery());
    }
    else {
        return null;
    }
}

ItI simplified the if/else code flow to take advantage of early returns. getUpdateAttribute is also generic over T because your attributes can be various types, like Integer and String.

  Finally, I makemade it private so your public attribute fetchers are the only interface exposed. Those attribute fetchers then become:

public static Long getChatId(Update update) {
    return getUpdateAttribute(
        Message::getChatId,
        callbackQuery -> callbackQuery.getMessage().getChatId()
    );
}

public static String getUserName(Update update) {
    return getUpdateAttribute(
        message -> message.getFrom().getUserName(),
        callbackQuery -> callbackQuery.getFrom().getUserName()
    );
}

public static String getInputUserData(Update update) {
    return getUpdateAttribute(
        Message::getText,
        CallbackQuery::getData
    );
}

public static Integer getMessageId(Update update) {
    return getUpdateAttribute(
        Message::getMessageId,
        callbackQuery -> callbackQuery.getMessage().getMessageId()
    );
}

Apart from this de-duplication, there is something else you can potentially improve. I'm not familiar with the Telegram API, but if it is possible that a message may have neither a message nor a callback query, then returning null seems like a valid response, in which case you may want to return Optional<T> from getUpdateAttribute (and all the other attribute fetchers), as that would signal your intent better.

Assuming Update#getMessage() is of type Message and Update#getCallbackQuery() is of type CallbackQuery:

You can make a function getUpdateAttribute that receives higher-order functions as handlers for the situation where your update has a message or callback query as follows.

private static <T> T getUpdateAttribute(Update update,
                                        Function<Message, T> messageFunc,
                                        Function<CallbackQuery, T> callbackQueryFunc) {
    if (updateHasMessage(update)) {
        return messageFunc.apply(update.getMessage());
    }
    else if (updateHasCallbackQuery(update)) {
        return callbackQueryFunc.apply(update.getCallbackQuery());
    }
    else {
        return null;
    }
}

It is generic over T because your attributes can be various types, like Integer and String.

  I make it private so your public attribute fetchers are the only interface exposed. Those attribute fetchers then become:

public static Long getChatId(Update update) {
    return getUpdateAttribute(
        Message::getChatId,
        callbackQuery -> callbackQuery.getMessage().getChatId()
    );
}

public static String getUserName(Update update) {
    return getUpdateAttribute(
        message -> message.getFrom().getUserName(),
        callbackQuery -> callbackQuery.getFrom().getUserName()
    );
}

public static String getInputUserData(Update update) {
    return getUpdateAttribute(
        Message::getText,
        CallbackQuery::getData
    );
}

public static Integer getMessageId(Update update) {
    return getUpdateAttribute(
        Message::getMessageId,
        callbackQuery -> callbackQuery.getMessage().getMessageId()
    );
}

Assuming Update#getMessage() is of type Message and Update#getCallbackQuery() is of type CallbackQuery:

You can make a function getUpdateAttribute that receives higher-order functions as handlers for the situation where your update has a message or callback query as follows.

private static <T> T getUpdateAttribute(Update update,
                                        Function<Message, T> messageFunc,
                                        Function<CallbackQuery, T> callbackQueryFunc) {
    if (updateHasMessage(update)) {
        return messageFunc.apply(update.getMessage());
    }
    if (updateHasCallbackQuery(update)) {
        return callbackQueryFunc.apply(update.getCallbackQuery());
    }

    return null;
}

I simplified the if/else code flow to take advantage of early returns. getUpdateAttribute is also generic over T because your attributes can be various types, like Integer and String. Finally, I made it private so your public attribute fetchers are the only interface exposed. Those attribute fetchers then become:

public static Long getChatId(Update update) {
    return getUpdateAttribute(
        Message::getChatId,
        callbackQuery -> callbackQuery.getMessage().getChatId()
    );
}

public static String getUserName(Update update) {
    return getUpdateAttribute(
        message -> message.getFrom().getUserName(),
        callbackQuery -> callbackQuery.getFrom().getUserName()
    );
}

public static String getInputUserData(Update update) {
    return getUpdateAttribute(
        Message::getText,
        CallbackQuery::getData
    );
}

public static Integer getMessageId(Update update) {
    return getUpdateAttribute(
        Message::getMessageId,
        callbackQuery -> callbackQuery.getMessage().getMessageId()
    );
}

Apart from this de-duplication, there is something else you can potentially improve. I'm not familiar with the Telegram API, but if it is possible that a message may have neither a message nor a callback query, then returning null seems like a valid response, in which case you may want to return Optional<T> from getUpdateAttribute (and all the other attribute fetchers), as that would signal your intent better.

Source Link
Mario Ishac
  • 977
  • 6
  • 15

Assuming Update#getMessage() is of type Message and Update#getCallbackQuery() is of type CallbackQuery:

You can make a function getUpdateAttribute that receives higher-order functions as handlers for the situation where your update has a message or callback query as follows.

private static <T> T getUpdateAttribute(Update update,
                                        Function<Message, T> messageFunc,
                                        Function<CallbackQuery, T> callbackQueryFunc) {
    if (updateHasMessage(update)) {
        return messageFunc.apply(update.getMessage());
    }
    else if (updateHasCallbackQuery(update)) {
        return callbackQueryFunc.apply(update.getCallbackQuery());
    }
    else {
        return null;
    }
}

It is generic over T because your attributes can be various types, like Integer and String.

I make it private so your public attribute fetchers are the only interface exposed. Those attribute fetchers then become:

public static Long getChatId(Update update) {
    return getUpdateAttribute(
        Message::getChatId,
        callbackQuery -> callbackQuery.getMessage().getChatId()
    );
}

public static String getUserName(Update update) {
    return getUpdateAttribute(
        message -> message.getFrom().getUserName(),
        callbackQuery -> callbackQuery.getFrom().getUserName()
    );
}

public static String getInputUserData(Update update) {
    return getUpdateAttribute(
        Message::getText,
        CallbackQuery::getData
    );
}

public static Integer getMessageId(Update update) {
    return getUpdateAttribute(
        Message::getMessageId,
        callbackQuery -> callbackQuery.getMessage().getMessageId()
    );
}