Factory: Notification Sender

Problem

Each input line is a channel (email, sms or push) and a message. Print the message with a prefix: Email: , SMS: or Push: . For any other channel print Unknown channel: followed by the channel name. Use a factory that creates the right sender object.

Constraints

  • 1 <= lines <= 10^4

Examples

Input

email hello world
fax hi

Output

Email: hello world
Unknown channel: fax

Solutions

Best approachTime O(n)Space O(n)

The loop never says new EmailSender(). When a new channel is added, only the factory changes.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Process lines.
 * Input   : Several lines.
 * Output  : One line per message.
 * Approach: Factory returns objects.
 * Time    : O(n)
 * Space   : O(n)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
        // Step 1: Every sender has the same method, so the caller does not need to know the real class.
        interface Sender {
            String send(String message);
        }

        static class EmailSender implements Sender {
            public String send(String message) {
                return "Email: " + message;
            }
        }

        static class SmsSender implements Sender {
            public String send(String message) {
                return "SMS: " + message;
            }
        }

        static class PushSender implements Sender {
            public String send(String message) {
                return "Push: " + message;
            }
        }

        // Step 2: The factory method chooses the class. It returns null for an unknown channel.
        static Sender create(String channel) {
            switch (channel) {
                case "email":
                    return new EmailSender();
                case "sms":
                    return new SmsSender();
                case "push":
                    return new PushSender();
                default:
                    return null;
            }
        }

    // This method solves the task. It receives the input and returns the answer.
    static String[] solve(String[] lines) {
        String[] output = new String[lines.length];
        for (int i = 0; i < lines.length; i++) {
            // Step 3: Split at the first space. The channel is the first word. The message is the rest.
            String[] parts = lines[i].split(" ", 2);

            // Step 4: Ask the factory for a sender. We use the sender without knowing its class.
            Sender sender = create(parts[0]);
            output[i] = sender == null ? "Unknown channel: " + parts[0] : sender.send(parts[1]);
        }
        return output;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        java.util.List<String> all = new java.util.ArrayList<>();
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine().trim();
            if (!line.isEmpty()) {
                all.add(line);
            }
        }
        String[] lines = all.toArray(new String[0]);
        System.out.println(String.join("\n", solve(lines)));
    }
}
Hints (1)
  1. Which part of the program knows the concrete classes?