Encapsulating object creation Static factory methods for Time

The normal way to create an instance of a class is to use a public constructor of the class. But there is another technique. A class can provide a public static factory method that returns an instance of the class. An advantage of static factory methods is that they have names that make the code easier to read.

In this problem, you have the class Time containing three fields: hour, minute and second. Implement the following static factory methods of this class:

noon() returns an instance initialized with 12 hours, 0 minutes, and 0 seconds.
midnight() returns an instance initialized with 0 hours, 0 minutes, and 0 seconds.
of(int hour, int minute, int second) returns an instance initialized with passed hour, minute and second if the passed arguments are correct (hour: 0-23, minute: 0-59, seconds: 0-59), otherwise, null.
ofSeconds(long seconds) returns an instance initialized with seconds passed since midnight; as an example, the invocation Time.ofSeconds(500000) must create an instance with 18 hours, 53 minutes and 20 seconds (days are skipped);
As you see, the methods are more readable than the same constructors. If you want to create an instance of Time representing noon, you can write:

Time noon = Time.noon();
Note:

do not change fields of the class Time;
in a real application, it may be better to throw an exception than return null when arguments are incorrect.
You must not read or output something in this problem. Just implement the static factory methods.

import java.util.Scanner;

class Time {

    public static final int SEC_LIMIT = 60;
    public static final int MIN_LIMIT = 60;
    public static final int HOUR_LIMIT = 24;
    int hour;
    int minute;
    int second;

    public static Time noon() {
        return of(12, 0, 0);
    }

    public static Time midnight() {
        return of(0, 0, 0);
    }

    public static Time ofSeconds(long seconds) {
        int second = (int) (seconds % SEC_LIMIT);
        int minute = (int) (seconds / SEC_LIMIT % MIN_LIMIT);
        int hour = (int) (seconds / SEC_LIMIT / MIN_LIMIT % HOUR_LIMIT);
        return of(hour, minute, second);
    }

    public static Time of(int hour, int minute, int second) {
        if (inValidRange(second, SEC_LIMIT)
                && inValidRange(minute, MIN_LIMIT)
                && inValidRange(hour, HOUR_LIMIT)
        ) {
            Time time = new Time();
            time.hour = hour;
            time.minute = minute;
            time.second = second;
            return time;
        }
        return null;
    }

    private static boolean inValidRange(int number, int upperLimit) {
        return number >= 0 && number < upperLimit;
    }
}

/* Do not change code below */
public class Main {

    public static void main(String[] args) {
        final Scanner scanner = new Scanner(System.in);

        final String type = scanner.next();
        Time time = null;

        switch (type) {
            case "noon":
                time = Time.noon();
                break;
            case "midnight":
                time = Time.midnight();
                break;
            case "hms":
                int h = scanner.nextInt();
                int m = scanner.nextInt();
                int s = scanner.nextInt();
                time = Time.of(h, m, s);
                break;
            case "seconds":
                time = Time.ofSeconds(scanner.nextInt());
                break;
            default:
                time = null;
                break;
        }

        if (time == null) {
            System.out.println(time);
        } else {
            System.out.println(String.format("%s %s %s", time.hour, time.minute, time.second));
        }
    }
}
posted @ 2020-09-21 14:33  longlong6296  阅读(241)  评论(0)    收藏  举报