ewhk9887/korean_code_reviews_from_github huggingface dataset:
@@ -0,0 +1,78 @@
+.login {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 100vh;
+  border: 1px solid #bdbdbd;
+  text-align: center;
+  background: rgb(250, 250, 250);
+
+  .login-container {
+    width: 350px;
+    height: 350px;
+    padding: 0 40px;
+    border: 1px solid silver;
+    border-radius: 5px;
+    background: #fff;
+    display: flex;
+    flex-direction: column;
+    justify-content: space-around;
+
+    .westagram-logo {
+      font-size: 45px;
+      font-family: "Lobster",
+        cursive;
+      color: black;
+    }
+
+    .login-form {
+
+      .login-input {
+        width: 100%;
+        height: 38px;
+        font-size: 12px;
+        padding: 0 20px;
+        margin-bottom: 10px;
+        border: 1px solid silver;
+        box-sizing: border-box;
+        border-radius: 5px;
+        background: rgba(238, 238, 238, 0.534);
+        color: #929292;
+        outline: 0;
+      }
+
+      .login-btn {
+        display: block;
+        width: 100%;
+        height: 32px;
+        margin-top: 10px;
+        border-radius: 5px;
+        color: #fff;
+        background: #b2dffc;
+        border: 1px solid #b2dffc;
+      }
+
+      .login-btn--active {
+        width: 100%;
+        height: 32px;
+        margin-top: 10px;
+        border: 1px solid #0095f6;
+        border-radius: 5px;
+        background: #0095f6;
+        color: #fff;
+      }
+    }
+
+    color: #0f5086;
+
+    .singUp {
+      font-size: 12px;
+      color: #0f5086;
+
+      a {
+        color: #0f5086;
+        text-decoration: none;
+      }
+    }
+  }
+}
\ No newline at end of file

리뷰: scss의 extends 문법 활용하면 좋겠네요
@@ -0,0 +1,78 @@
+.login {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 100vh;
+  border: 1px solid #bdbdbd;
+  text-align: center;
+  background: rgb(250, 250, 250);
+
+  .login-container {
+    width: 350px;
+    height: 350px;
+    padding: 0 40px;
+    border: 1px solid silver;
+    border-radius: 5px;
+    background: #fff;
+    display: flex;
+    flex-direction: column;
+    justify-content: space-around;
+
+    .westagram-logo {
+      font-size: 45px;
+      font-family: "Lobster",
+        cursive;
+      color: black;
+    }
+
+    .login-form {
+
+      .login-input {
+        width: 100%;
+        height: 38px;
+        font-size: 12px;
+        padding: 0 20px;
+        margin-bottom: 10px;
+        border: 1px solid silver;
+        box-sizing: border-box;
+        border-radius: 5px;
+        background: rgba(238, 238, 238, 0.534);
+        color: #929292;
+        outline: 0;
+      }
+
+      .login-btn {
+        display: block;
+        width: 100%;
+        height: 32px;
+        margin-top: 10px;
+        border-radius: 5px;
+        color: #fff;
+        background: #b2dffc;
+        border: 1px solid #b2dffc;
+      }
+
+      .login-btn--active {
+        width: 100%;
+        height: 32px;
+        margin-top: 10px;
+        border: 1px solid #0095f6;
+        border-radius: 5px;
+        background: #0095f6;
+        color: #fff;
+      }
+    }
+
+    color: #0f5086;
+
+    .singUp {
+      font-size: 12px;
+      color: #0f5086;
+
+      a {
+        color: #0f5086;
+        text-decoration: none;
+      }
+    }
+  }
+}
\ No newline at end of file

리뷰: 불필요한 주석은 삭제해주세요
@@ -0,0 +1,19 @@
+import React, { Component } from 'react';
+
+class Comment extends Component {
+  render() {
+    const { profile, name, content } = this.props;
+    return (
+      <li className="feeds-comment__reply">
+        <div className="user-feeds__profile--img">
+          <img src={profile} alt="피드사진" />
+        </div>
+        <b className="user-feeds__name--others">{name}</b>
+        <p>{content}</p>
+        <i className="far fa-heart icon"></i>
+      </li>
+    );
+  }
+}
+
+export default Comment;

리뷰: ```suggestion
          {!this.props.profile && (
            <img src={this.props.profile} alt="피드사진" />
          )
```
- !== 연산자 불필요해보입니다, 빈 문자열은 falsy 값이기에 not 연산자와 조합해서 빈문자열이 아닐때를 표현 가능합니다.
- true일 경우에만 렌더링되면 된다면 삼항연산자말고 && 연산자를 이용해보세요
@@ -0,0 +1,19 @@
+import React, { Component } from 'react';
+
+class Comment extends Component {
+  render() {
+    const { profile, name, content } = this.props;
+    return (
+      <li className="feeds-comment__reply">
+        <div className="user-feeds__profile--img">
+          <img src={profile} alt="피드사진" />
+        </div>
+        <b className="user-feeds__name--others">{name}</b>
+        <p>{content}</p>
+        <i className="far fa-heart icon"></i>
+      </li>
+    );
+  }
+}
+
+export default Comment;

리뷰: props 구조분해할당해서 사용하면 좋아보이네요
@@ -0,0 +1,43 @@
+import React, { Component } from 'react';
+import Comment from './Comment/Comment';
+import './CommentList.scss';
+
+class CommentList extends Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      commentList: [],
+    };
+  }
+  componentDidMount() {
+    fetch('http://localhost:3000/data/commentData_songhyun.json', {
+      method: 'GET',
+    })
+      .then(res => res.json())
+      .then(comments =>
+        this.setState({
+          commentList: comments,
+        })
+      );
+  }
+  render() {
+    const { commentList } = this.state;
+
+    return (
+      <ul className="feeds-comment__list">
+        {commentList.map(comment => {
+          return (
+            <Comment
+              key={comment.id}
+              name={comment.userName}
+              profile={comment.profile}
+              content={comment.content}
+            />
+          );
+        })}
+      </ul>
+    );
+  }
+}
+
+export default CommentList;

리뷰: data라는 광범위한 변수명보다는 의미가 드러나게 변수명 지어주세요
@@ -1,7 +1,77 @@
-import React from 'react';
+import React, { Component } from 'react';
+import './Login.scss';
 
-function Login() {
-  return <div>Nav bar</div>;
+class Login extends Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      id: '',
+      pwd: '',
+    };
+  }
+
+  handleInput = event => {
+    const { name, value } = event.target;
+
+    this.setState({
+      [name]: value,
+    });
+  };
+
+  handleSubmit = event => {
+    event.preventDefault();
+    this.handleValidate();
+
+    this.setState({
+      id: '',
+      pwd: '',
+    });
+  };
+
+  render() {
+    const { id, pwd } = this.state;
+    return (
+      <div className="login">
+        <div className="login-container">
+          <h2 className="westagram-logo">westagram</h2>
+          <form className="login-form" onSubmit={this.handleSubmit}>
+            <input
+              type="email"
+              className="login-input"
+              name="id"
+              value={this.state.id}
+              placeholder="전화번호, 사용자 이름 또는 이메일"
+              onChange={this.handleInput}
+              aria-label="이메일"
+            />
+            <input
+              type="password"
+              className="login-input"
+              name="pwd"
+              value={this.state.pwd}
+              placeholder="비밀번호"
+              autoComplete="off"
+              aria-label="비밀번호"
+              onChange={this.handleInput}
+            />
+            <button
+              type="submit"
+              className={
+                id.includes('@') && pwd.length >= 5
+                  ? 'login-btn--active'
+                  : 'login-btn'
+              }
+            >
+              로그인
+            </button>
+          </form>
+          <p className="singUp">
+            <span>비밀번호 찾기</span> / <a href="/signup">가입하기</a>
+          </p>
+        </div>
+      </div>
+    );
+  }
 }
 
 export default Login;

리뷰: 네 코드 리뷰 적용하겠습니다.
@@ -1,7 +1,77 @@
-import React from 'react';
+import React, { Component } from 'react';
+import './Login.scss';
 
-function Login() {
-  return <div>Nav bar</div>;
+class Login extends Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      id: '',
+      pwd: '',
+    };
+  }
+
+  handleInput = event => {
+    const { name, value } = event.target;
+
+    this.setState({
+      [name]: value,
+    });
+  };
+
+  handleSubmit = event => {
+    event.preventDefault();
+    this.handleValidate();
+
+    this.setState({
+      id: '',
+      pwd: '',
+    });
+  };
+
+  render() {
+    const { id, pwd } = this.state;
+    return (
+      <div className="login">
+        <div className="login-container">
+          <h2 className="westagram-logo">westagram</h2>
+          <form className="login-form" onSubmit={this.handleSubmit}>
+            <input
+              type="email"
+              className="login-input"
+              name="id"
+              value={this.state.id}
+              placeholder="전화번호, 사용자 이름 또는 이메일"
+              onChange={this.handleInput}
+              aria-label="이메일"
+            />
+            <input
+              type="password"
+              className="login-input"
+              name="pwd"
+              value={this.state.pwd}
+              placeholder="비밀번호"
+              autoComplete="off"
+              aria-label="비밀번호"
+              onChange={this.handleInput}
+            />
+            <button
+              type="submit"
+              className={
+                id.includes('@') && pwd.length >= 5
+                  ? 'login-btn--active'
+                  : 'login-btn'
+              }
+            >
+              로그인
+            </button>
+          </form>
+          <p className="singUp">
+            <span>비밀번호 찾기</span> / <a href="/signup">가입하기</a>
+          </p>
+        </div>
+      </div>
+    );
+  }
 }
 
 export default Login;

리뷰: 감사합니다 ㅎㅎ
@@ -0,0 +1,22 @@
+package common;
+
+import domain.gameresult.GameResult;
+import domain.gameresult.GameResults;
+import domain.player.Player;
+import domain.player.Players;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class PlayerGameResult {
+    public static Map<String, String> match(Players players, GameResults gameResults) {
+        Map<String, String> result = new HashMap<>();
+        for (Player player : players.getPlayers()) {
+            String gameResultName = gameResults.getGameResults().stream()
+                    .filter(gameResult -> gameResult.getPosition().equals(player.getPosition()))
+                    .map(GameResult::getName).findFirst().get();
+            result.put(player.getName(), gameResultName);
+        }
+        return result;
+    }
+}

리뷰: 이 클래스가 꼭 필요할까요? common 패키지에 위치한 이유와 각 책임을 다른 클래스들로 위임할 수 없을지 고민해보면 좋을 것 같습니다.
@@ -0,0 +1,22 @@
+package common;
+
+import domain.gameresult.GameResult;
+import domain.gameresult.GameResults;
+import domain.player.Player;
+import domain.player.Players;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class PlayerGameResult {
+    public static Map<String, String> match(Players players, GameResults gameResults) {
+        Map<String, String> result = new HashMap<>();
+        for (Player player : players.getPlayers()) {
+            String gameResultName = gameResults.getGameResults().stream()
+                    .filter(gameResult -> gameResult.getPosition().equals(player.getPosition()))
+                    .map(GameResult::getName).findFirst().get();
+            result.put(player.getName(), gameResultName);
+        }
+        return result;
+    }
+}

리뷰: command + ,
java code style
method chaining multi line
부분에 체크하고 정렬하시면 가독성 좋게 정렬됩니다 ~ 추천드려요
@@ -0,0 +1,22 @@
+package common;
+
+import domain.gameresult.GameResult;
+import domain.gameresult.GameResults;
+import domain.player.Player;
+import domain.player.Players;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class PlayerGameResult {
+    public static Map<String, String> match(Players players, GameResults gameResults) {
+        Map<String, String> result = new HashMap<>();
+        for (Player player : players.getPlayers()) {
+            String gameResultName = gameResults.getGameResults().stream()
+                    .filter(gameResult -> gameResult.getPosition().equals(player.getPosition()))
+                    .map(GameResult::getName).findFirst().get();
+            result.put(player.getName(), gameResultName);
+        }
+        return result;
+    }
+}

리뷰: get 으로 가져와서 구현하는 것보다 Tell don't ask 원칙을 적용해보면 어떨까요?
@@ -0,0 +1,46 @@
+package domain.player;
+
+import domain.line.Line;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Players {
+
+    private List<Player> players;
+
+    public Players(List<Player> players) {
+        this.players = new ArrayList<>(players);
+    }
+
+    public List<Player> getPlayers() {
+        return Collections.unmodifiableList(players);
+    }
+
+    public List<String> toPlayerNames() {
+        return players.stream()
+                .map(player -> player.getName())
+                .collect(Collectors.toList());
+    }
+
+    public int size() {
+        return players.size();
+    }
+
+    public void moveAll(List<Line> lines) {
+        lines.forEach(this::moveOneLine);
+    }
+
+    public void moveOneLine(Line line) {
+        players.forEach(player -> player.move(line.findCurrentPointDirection(player.getPosition().getX())));
+    }
+
+    public boolean isContain(String playerName) {
+        if (!toPlayerNames().contains(playerName)) {
+            return false;
+        }
+        return true;
+    }
+}

리뷰: getPlayerNames 는 어떨까요
@@ -0,0 +1,46 @@
+package domain.player;
+
+import domain.line.Line;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Players {
+
+    private List<Player> players;
+
+    public Players(List<Player> players) {
+        this.players = new ArrayList<>(players);
+    }
+
+    public List<Player> getPlayers() {
+        return Collections.unmodifiableList(players);
+    }
+
+    public List<String> toPlayerNames() {
+        return players.stream()
+                .map(player -> player.getName())
+                .collect(Collectors.toList());
+    }
+
+    public int size() {
+        return players.size();
+    }
+
+    public void moveAll(List<Line> lines) {
+        lines.forEach(this::moveOneLine);
+    }
+
+    public void moveOneLine(Line line) {
+        players.forEach(player -> player.move(line.findCurrentPointDirection(player.getPosition().getX())));
+    }
+
+    public boolean isContain(String playerName) {
+        if (!toPlayerNames().contains(playerName)) {
+            return false;
+        }
+        return true;
+    }
+}

리뷰: player.getPositionX(); 로 디미터법칙을 지켜보면 어떨까요
@@ -0,0 +1,32 @@
+package domain.line;
+
+import domain.point.Direction;
+import domain.point.Point;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Line {
+    private List<Point> points;
+
+    public Line(List<Point> points) {
+        this.points = new ArrayList<>(points);
+    }
+
+    public List<Point> getPoints() {
+        return Collections.unmodifiableList(points);
+    }
+
+    public List<Boolean> toBoolean() {
+        return points.stream()
+                .limit(points.size() - 1)
+                .map(point -> point.isRight())
+                .collect(Collectors.toList());
+    }
+
+    public Direction findCurrentPointDirection(int x) {
+        return points.get(x).getDirection();
+    }
+}

리뷰: getDirectionFlags() 는 어떤가요?
@@ -0,0 +1,28 @@
+package domain.gameresult;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class GameResults {
+    private List<GameResult> gameResults;
+
+    public GameResults(List<GameResult> gameResults) {
+        this.gameResults = new ArrayList<>(gameResults);
+    }
+
+    public List<GameResult> getGameResults() {
+        return Collections.unmodifiableList(gameResults);
+    }
+
+    public List<String> toGameResultNames() {
+        return gameResults.stream()
+                .map(gameResult -> gameResult.getName())
+                .collect(Collectors.toList());
+    }
+
+    public int size() {
+        return gameResults.size();
+    }
+}

리뷰: 객체의 상태를 변환하는게 아니고 반환하는 것이므로 get 이라는 동사어가 어울릴 것 같습니다
@@ -0,0 +1,32 @@
+package domain.line;
+
+import domain.point.Direction;
+import domain.point.Point;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Line {
+    private List<Point> points;
+
+    public Line(List<Point> points) {
+        this.points = new ArrayList<>(points);
+    }
+
+    public List<Point> getPoints() {
+        return Collections.unmodifiableList(points);
+    }
+
+    public List<Boolean> toBoolean() {
+        return points.stream()
+                .limit(points.size() - 1)
+                .map(point -> point.isRight())
+                .collect(Collectors.toList());
+    }
+
+    public Direction findCurrentPointDirection(int x) {
+        return points.get(x).getDirection();
+    }
+}

리뷰: this.points = points 로 하면 어떻게 될까요?
@@ -0,0 +1,32 @@
+package domain.line;
+
+import domain.point.Direction;
+import domain.point.Point;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Line {
+    private List<Point> points;
+
+    public Line(List<Point> points) {
+        this.points = new ArrayList<>(points);
+    }
+
+    public List<Point> getPoints() {
+        return Collections.unmodifiableList(points);
+    }
+
+    public List<Boolean> toBoolean() {
+        return points.stream()
+                .limit(points.size() - 1)
+                .map(point -> point.isRight())
+                .collect(Collectors.toList());
+    }
+
+    public Direction findCurrentPointDirection(int x) {
+        return points.get(x).getDirection();
+    }
+}

리뷰: unmodifiable 로 한번 감싼 이유가 있으실까요?
@@ -0,0 +1,32 @@
+package domain.line;
+
+import domain.point.Direction;
+import domain.point.Point;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Line {
+    private List<Point> points;
+
+    public Line(List<Point> points) {
+        this.points = new ArrayList<>(points);
+    }
+
+    public List<Point> getPoints() {
+        return Collections.unmodifiableList(points);
+    }
+
+    public List<Boolean> toBoolean() {
+        return points.stream()
+                .limit(points.size() - 1)
+                .map(point -> point.isRight())
+                .collect(Collectors.toList());
+    }
+
+    public Direction findCurrentPointDirection(int x) {
+        return points.get(x).getDirection();
+    }
+}

리뷰: array out of index 에러는 걱정하지 않아도 되는건가요?
@@ -0,0 +1,32 @@
+package domain.line;
+
+import domain.point.Direction;
+import domain.point.Point;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Line {
+    private List<Point> points;
+
+    public Line(List<Point> points) {
+        this.points = new ArrayList<>(points);
+    }
+
+    public List<Point> getPoints() {
+        return Collections.unmodifiableList(points);
+    }
+
+    public List<Boolean> toBoolean() {
+        return points.stream()
+                .limit(points.size() - 1)
+                .map(point -> point.isRight())
+                .collect(Collectors.toList());
+    }
+
+    public Direction findCurrentPointDirection(int x) {
+        return points.get(x).getDirection();
+    }
+}

리뷰: find 와 get 메서드 네이밍의 차이가 무엇일까요?
@@ -0,0 +1,32 @@
+package domain.line;
+
+import domain.point.Direction;
+import domain.point.Point;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Line {
+    private List<Point> points;
+
+    public Line(List<Point> points) {
+        this.points = new ArrayList<>(points);
+    }
+
+    public List<Point> getPoints() {
+        return Collections.unmodifiableList(points);
+    }
+
+    public List<Boolean> toBoolean() {
+        return points.stream()
+                .limit(points.size() - 1)
+                .map(point -> point.isRight())
+                .collect(Collectors.toList());
+    }
+
+    public Direction findCurrentPointDirection(int x) {
+        return points.get(x).getDirection();
+    }
+}

리뷰: points 를 Line 으로 추상화하신 것 같은데 getPoints() 가 필요한 케이스가 있을까요?
@@ -0,0 +1,21 @@
+package domain.gameresult;
+
+import domain.player.Position;
+
+public class GameResult {
+    private GameResultName name;
+    private Position position;
+
+    public GameResult(GameResultName name, Position position) {
+        this.name = name;
+        this.position = position;
+    }
+
+    public String getName() {
+        return name.getName();
+    }
+
+    public Position getPosition() {
+        return position;
+    }
+}

리뷰: 생성자와 getter 뿐인데 이건 DTO 역할인가요?
@@ -0,0 +1,17 @@
+package domain.gameresult;
+
+import domain.player.Position;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class GameResultFactory {
+
+    public static GameResults from(List<GameResultName> gameResultNames, int positionY) {
+        List<GameResult> gameResults = new ArrayList<>();
+        for (int i = 0; i < gameResultNames.size(); i++) {
+            gameResults.add(new GameResult(gameResultNames.get(i), new Position(i, positionY)));
+        }
+        return new GameResults(gameResults);
+    }
+}
\ No newline at end of file

리뷰: 생성을 Factory 로 모두 위임한 이유가 궁금합니다.
Factory 없이 도메인 클래스의 정적 팩토리 메서드를 통해 생성하면 어떤 안 좋은 점이 있을까요?
그리고 GameResultsFactory 가 아닐까요?
@@ -0,0 +1,21 @@
+package domain.ladder;
+
+public class Height {
+    private static final String INPUT_POSITIVE_MESSAGE = "[ERROR] 높이는 0 초과를 입력합니다.";
+    private int height;
+
+    public Height(int height) {
+        validatePositive(height);
+        this.height = height;
+    }
+
+    public void validatePositive(int height) {
+        if (height <= 0) {
+            throw new IllegalArgumentException(INPUT_POSITIVE_MESSAGE);
+        }
+    }
+
+    public int getHeight() {
+        return height;
+    }
+}

리뷰: private 이어야 하지 않을까요~?
@@ -0,0 +1,18 @@
+package domain.ladder;
+
+import domain.line.Line;
+import domain.line.LineGenerator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LadderGenerator {
+
+    public static Ladder generate(int ladderHeight, int playerCount) {
+        List<Line> lines = new ArrayList<>();
+        for (int i = 0; i < ladderHeight; i++) {
+            lines.add(LineGenerator.generate(playerCount));
+        }
+        return new Ladder(lines);
+    }
+}

리뷰: Ladder 로 위임하면 어떨까요
@@ -0,0 +1,49 @@
+package domain.line;
+
+import domain.point.Point;
+import domain.point.RandomPointGenerator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LineGenerator {
+
+    public static Line generate(int playerCount) {
+        List<Point> points = new ArrayList<>();
+        if (playerCount == 1) {
+            return new Line(generateSingleVerticalLine(points));
+        }
+
+        return new Line(generateMultiVerticalLine(points, playerCount));
+    }
+
+    private static Point generateOnlyFirstExist() {
+        return Point.onlyFirstExist();
+    }
+
+    private static Point generateFirstPoint() {
+        return Point.first(RandomPointGenerator.generate());
+    }
+
+    private static Point generateMiddlePoint(Point prePoint) {
+        return Point.next(prePoint, RandomPointGenerator.generate());
+    }
+
+    private static Point generateLastPoint(Point prePoint) {
+        return Point.last(prePoint);
+    }
+
+    private static List<Point> generateSingleVerticalLine(List<Point> points) {
+        points.add(generateOnlyFirstExist());
+        return points;
+    }
+
+    private static List<Point> generateMultiVerticalLine(List<Point> points, int playerCount) {
+        points.add(generateFirstPoint());
+        for (int i = 0; i < playerCount - 2; i++) {
+            points.add(generateMiddlePoint(points.get(i)));
+        }
+        points.add(generateLastPoint(points.get(points.size() - 1)));
+        return points;
+    }
+}

리뷰: Line 뿐만 아니라 Point, List<Point> 타입까지 생성하고 있는데
각자 위임될만한 도메인 클래스가 있지 않을까요? 한번 고민해보면 좋을 것 같습니다.