1. 긴 함수 개념 정의

2. 임시 변수를 질의 함수로 바꾸기

3. 매개변수 객체 만들기

4. 필드 변수로 빼서 하는 방법

5. 객체 통째로 넘기기

1. 긴 함수 개념 정의

1-1) 짧은 함수 vs 긴 함수

1-2) 사용할 수 있는 리팩토링 기술

2. 임시 변수를 질의 함수로 바꾸기

2-1) 개념

2-2) 리팩토링 전

2-2)-1. class StudyDashboard

public class StudyDashboard {

    public static void main(String[] args) throws IOException,
                                                InterruptedException {
        StudyDashboard studyDashboard = new StudyDashboard();
        studyDashboard.print();
    }

    private void print() throws IOException, InterruptedException {
        GitHub gitHub = GitHub.connect();
        GHRepository repository = gitHub
                .getRepository("whiteship/live-study");
        List<Participant> participants = new CopyOnWriteArrayList<>();

        int totalNumberOfEvents = 15;
        ExecutorService service = Executors.newFixedThreadPool(8);
        CountDownLatch latch = new CountDownLatch(totalNumberOfEvents);

        for (int index = 1 ; index <= totalNumberOfEvents ; index++) {
            int eventId = index;
            service.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        GHIssue issue = repository.getIssue(eventId);
                        List<GHIssueComment> comments = issue.getComments();

                        for (GHIssueComment comment : comments) {
                            String username = comment.getUserName();
                            boolean isNewUser = participants.stream().noneMatch(
                                    p -> p.username().equals(username)
                            );
                            Participant participant = null;
                            if (isNewUser) {
                                participant = new Participant(username);
                                participants.add(participant);
                            } else {
                                participant = participants.stream()
																	.filter(
                                        p -> p.username().equals(username)
                                ).findFirst().orElseThrow();
                            }
                            participant.setHomeworkDone(eventId);
                        }
                        latch.countDown();
                    } catch (IOException e) {
		                        throw new IllegalArgumentException(e);
                    }
                }
            });
        }

        latch.await();
        service.shutdown();
				
				// markdownprint(마트다운으로 출력하는 부분)
        try (FileWriter fileWriter = new FileWriter("participants.md");
             PrintWriter writer = new PrintWriter(fileWriter)) {
            participants.sort(Comparator.comparing(Participant::username));

            writer.print(header(totalNumberOfEvents, participants.size()));

            participants.forEach(p -> {
                // RateCount(참여율 계산식)
								long count = p.homework().values().stream()
                        .filter(v -> v == true)
                        .count();
								// Rete(참여율)
                double rate = count * 100 / totalNumberOfEvents;

								// Markdown
                String markdownForHomework = 
												String.format("| %s %s | %.2f%% |\\n", p.username(),
                        checkMark(p, totalNumberOfEvents), rate);

                writer.print(markdownForHomework);
            });
        }
    }
}

2-2)-2. private void print()

2-3) 리팩토링 후

2-3)-1. class StudyDashboard

public class StudyDashboard {

    public static void main(String[] args) throws IOException,
                                                InterruptedException {
        StudyDashboard studyDashboard = new StudyDashboard();
        studyDashboard.print();
    }

    private void print() throws IOException, InterruptedException {
        GitHub gitHub = GitHub.connect();
        GHRepository repository = gitHub
                .getRepository("whiteship/live-study");
        List<Participant> participants = new CopyOnWriteArrayList<>();

        int totalNumberOfEvents = 15;
        ExecutorService service = Executors.newFixedThreadPool(8);
        CountDownLatch latch = new CountDownLatch(totalNumberOfEvents);

        for (int index = 1 ; index <= totalNumberOfEvents ; index++) {
            int eventId = index;
            service.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        GHIssue issue = repository.getIssue(eventId);
                        List<GHIssueComment> comments = issue.getComments();

                        for (GHIssueComment comment : comments) {
                            String username = comment.getUserName();
                            boolean isNewUser = participants.stream().noneMatch(
                                    p -> p.username().equals(username)
                            );
                            Participant participant = null;
                            if (isNewUser) {
                                participant = new Participant(username);
                                participants.add(participant);
                            } else {
                                participant = participants.stream()
																	.filter(
                                        p -> p.username().equals(username)
                                ).findFirst().orElseThrow();
                            }
                            participant.setHomeworkDone(eventId);
                        }
                        latch.countDown();
                    } catch (IOException e) {
		                        throw new IllegalArgumentException(e);
                    }
                }
            });
        }

        latch.await();
        service.shutdown();
				
				try (FileWriter fileWriter = new FileWriter("participants.md");
		     PrintWriter writer = new PrintWriter(fileWriter)) {
					participants.sort(Comparator.comparing(Participant::username));
		
					writer.print(header(totalNumberOfEvents, participants.size()));
		
					participants.forEach(p -> {
						double rate = getRate(totalNumberOfEvents, p);
		
						String markdownForHomework = 
										getMarkdownForParticipant(totalNumberOfEvents, p, rate);
						writer.print(markdownForHomework);
					});
				}
		}
	
		// Query Function
		private double getRate(int totalNumberOfEvents, Participant p) {
			
			// RateCount
			long count = p.homework().values().stream()
					.filter(v -> v == true)
					.count();
			
			// Rate
			double rate = count * 100 / totalNumberOfEvents;
			
			return rate;
		}
	
		// ParticipantMarkdown
		private String getMarkdownForParticipant(int totalNumberOfEvents, 
																									Participant p, double rate) {
			String markdownForHomework = 
						String.format("| %s %s | %.2f%% |\\n", p.username(), 
							checkMark(p, totalNumberOfEvents), rate);
			return markdownForHomework;
		}
}

2-3)-2. private void print()

3. 매개변수 객체 만들기

3-1) 개념

3-2) 리팩토링 전

3-2)-1. private void print()

public class StudyDashboard {

    public static void main(String[] args) throws IOException, 
																									InterruptedException {
        StudyDashboard studyDashboard = new StudyDashboard();
        studyDashboard.print();
    }

    private void print() throws IOException, InterruptedException {
        GitHub gitHub = GitHub.connect();
        GHRepository repository = gitHub
														.getRepository("whiteship/live-study");
        List<Participant> participants = new CopyOnWriteArrayList<>();

        int totalNumberOfEvents = 15;
        ExecutorService service = Executors.newFixedThreadPool(8);
        CountDownLatch latch = new CountDownLatch(totalNumberOfEvents);

        for (int index = 1 ; index <= totalNumberOfEvents ; index++) {
            int eventId = index;
            service.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        GHIssue issue = repository.getIssue(eventId);
                        List<GHIssueComment> comments = issue.getComments();

                        for (GHIssueComment comment : comments) {
                            String username = comment.getUserName();
                            boolean isNewUser = participants.stream()
																	.noneMatch(
																			p -> p.username().equals(username)
																	);
                            Participant participant = null;
                            if (isNewUser) {
                                participant = new Participant(username);
                                participants.add(participant);
                            } else {
                                participant = participants.stream()
																	.filter(
																			p -> p.username().equals(username)
																	).findFirst().orElseThrow();
                            }

                            participant.setHomeworkDone(eventId);
                        }

                        latch.countDown();
                    } catch (IOException e) {
                        throw new IllegalArgumentException(e);
                    }
                }
            });
        }
        latch.await();
        service.shutdown();

        try (FileWriter fileWriter = new FileWriter("participants.md");
             PrintWriter writer = new PrintWriter(fileWriter)) {
            participants.sort(Comparator.comparing(Participant::username));

            writer.print(header(totalNumberOfEvents, participants.size()));

            participants.forEach(p -> {
                String markdownForHomework = 
												getMarkdownForParticipant(totalNumberOfEvents, p);
                writer.print(markdownForHomework);
            });
        }
    }

    private double getRate(int totalNumberOfEvents, Participant p) {
        long count = p.homework().values().stream()
                .filter(v -> v == true)
                .count();
        double rate = count * 100 / totalNumberOfEvents;
        return rate;
    }

    private String getMarkdownForParticipant(int totalNumberOfEvents, 
																												Participant p) {
        return String.format(
							"| %s %s | %.2f%% |\\n", p.username(), 
							checkMark(p, totalNumberOfEvents), 
							getRate(totalNumberOfEvents, p)
				);
    }
}

3-3) 리팩토링 후

public class StudyDashboard {

    public static void main(String[] args) throws IOException, 
																							InterruptedException {
        StudyDashboard studyDashboard = new StudyDashboard();
        studyDashboard.print();
    }

    private void print() throws IOException, InterruptedException {
        GitHub gitHub = GitHub.connect();
        GHRepository repository = gitHub
														.getRepository("whiteship/live-study");
        List<Participant> participants = new CopyOnWriteArrayList<>();

        int totalNumberOfEvents = 15;
        ExecutorService service = Executors.newFixedThreadPool(8);
        CountDownLatch latch = new CountDownLatch(totalNumberOfEvents);

        for (int index = 1 ; index <= totalNumberOfEvents ; index++) {
            int eventId = index;
            service.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        GHIssue issue = repository.getIssue(eventId);
                        List<GHIssueComment> comments = issue.getComments();

                        for (GHIssueComment comment : comments) {
                            String username = comment.getUserName();
                            boolean isNewUser = participants.stream()
																	.noneMatch(
																			p -> p.username().equals(username)
																	);
                            Participant participant = null;
                            if (isNewUser) {
                                participant = new Participant(username);
                                participants.add(participant);
                            } else {
                                participant = participants.stream()
																	.filter(
																			p -> p.username().equals(username)
																	).findFirst().orElseThrow();
                            }

                            participant.setHomeworkDone(eventId);
                        }

                        latch.countDown();
                    } catch (IOException e) {
                        throw new IllegalArgumentException(e);
                    }
                }
            });
        }
        latch.await();
        service.shutdown();

        try (FileWriter fileWriter = new FileWriter("participants.md");
             PrintWriter writer = new PrintWriter(fileWriter)) {
            participants.sort(Comparator.comparing(Participant::username));

            writer.print(header(totalNumberOfEvents, participants.size()));

            participants.forEach(p -> {
                String markdownForHomework = 
												getMarkdownForParticipant(totalNumberOfEvents, p);
                writer.print(markdownForHomework);
            });
        }
    }

    private double getRate(int totalNumberOfEvents, Participant p) {
        long count = p.homework().values().stream()
                .filter(v -> v == true)
                .count();
        double rate = count * 100 / totalNumberOfEvents;
        return rate;
    }

		// Introduce Parameter Object
		private double getRate(ParticipantPrinter participantPrinter) {
        long count = participantPrinter.getP().homework().values().stream()
                .filter(v -> v == true)
                .count();
        double rate = count * 100 / participantPrinter
																					.getTotalNumberOfEvents();
        return rate;
    }

    private String getMarkdownForParticipant(int totalNumberOfEvents, 
																												Participant p) {
        return String.format(
							"| %s %s | %.2f%% |\\n", p.username(), 
							checkMark(p, totalNumberOfEvents), 
							getRate(totalNumberOfEvents, p)
				);
    }
}

4. 필드 변수로 빼서 하는 방법

5. 객체 통째로 넘기기