Java Design Issue: Enforce method call sequence

后端 未结 12 575
青春惊慌失措
青春惊慌失措 2021-02-02 05:27

There is a question which was recently asked to me in an interview.

Problem: There is a class meant to profile the execution time of the code. The class

12条回答
  •  北恋
    北恋 (楼主)
    2021-02-02 05:50

    I'm going to suggest that enforcing the method call sequence is solving the wrong problem; the real problem is a unfriendly interface where the user must be aware of the state of the stopwatch. The solution is to remove any requirement to know the state of the StopWatch.

    public class StopWatch {
    
        private Logger log = Logger.getLogger(StopWatch.class);
    
        private boolean firstMark = true;
        private long lastMarkTime;
        private long thisMarkTime;
        private String lastMarkMsg;
        private String thisMarkMsg;
    
        public TimingResult mark(String msg) {
            lastMarkTime = thisMarkTime;
            thisMarkTime = System.currentTimeMillis();
    
            lastMarkMsg = thisMarkMsg;
            thisMarkMsg = msg;
    
            String timingMsg;
            long elapsed;
            if (firstMark) {
                elapsed = 0;
                timingMsg = "First mark: [" + thisMarkMsg + "] at time " + thisMarkTime;
            } else {
                elapsed = thisMarkTime - lastMarkTime;
                timingMsg = "Mark: [" + thisMarkMsg + "] " + elapsed + "ms since mark [" + lastMarkMsg + "]";
            }
    
            TimingResult result = new TimingResult(timingMsg, elapsed);
            log.debug(result.msg);
            firstMark = false;
            return result;
        }
    
    }
    

    This allows a simple use of the mark method with a result returned and logging included.

    StopWatch stopWatch = new StopWatch();
    
    TimingResult r;
    r = stopWatch.mark("before loop 1");
    System.out.println(r);
    
    for (int i=0; i<100; i++) {
        slowThing();
    }
    
    r = stopWatch.mark("after loop 1");
    System.out.println(r);
    
    for (int i=0; i<100; i++) {
        reallySlowThing();
    }
    
    r = stopWatch.mark("after loop 2");
    System.out.println(r);
    

    This gives the nice result of;

    First mark: [before loop 1] at time 1436537674704
    Mark: [after loop 1] 1037ms since mark [before loop 1]
    Mark: [after loop 2] 2008ms since mark [after loop 1]

提交回复
热议问题