์ํ ์ฐธ์กฐ๋ ์์กด ๊ด๊ณ์ ์ฌ์ดํด์ด ์๊ธฐ๋ ์ํฉ์ผ๋ก ๋ํ์ ์ผ๋ก ๊ฐ์ฒด๊ฐ ์๋ก ์๋ฐฉํฅ ์ฐธ์กฐ๋ฅผ ํ๋ ์ํฉ์ด ์๋ค.
@Data
class Team {
private long id;
private String name;
private List<Member> members;
}
@Data
class Member {
private long id;
private String name;
private Team myTeam;
}
@Data
@NoArgsConstructor
@Entity(name = "team")
class TeamJpaEntity {
@Id
private String id;
@Column
private String name;
@OneToMany(mappedBy = "myTeam")
private List<MemberJpaEntity> members;
}
@Data
@NoArgsConstructor
@Entity(name = "member")
class MemberJpaEntity {
@Id
private String id;
@Column
private String name;
@ManyToOne
@JoinColumn(name = "my_team_id")
private TeamJpaEntity myTeam;
}
@Service
class TeamService {
@Autowired
private MemberService memberService;
...
}
@Service
class MemberService {
@Autowired
private TeamService teamService;
...
}
JPA๋ฅผ ์ฌ์ฉํ ๋ ํ ์ด๋ธ์ ํ ๋๋ก ์ํฐํฐ๋ฅผ ๋ง๋ค๋ค๋ณด๋ฉด ๋ ๋ฒ์งธ ์ฝ๋์ฒ๋ผ ์ธ๋ํค๋ฅผ ์๋ฐฉํฅ ๋งคํ์ผ๋ก ์์ฑํ๊ณค ํ๋๋ฐ ์ด๋ ์ํ ์ฐธ์กฐ์ ํด๋นํ๋ ๊ฒ์ด๋ค!
์คํ๋ง์ ์ฌ์ฉํ๋ฉด์ ์ด๋ฌํ ๋ฌธ์ ์ ๋ํด์ ๊ณ ๋ฏผํด๋ณธ ์ ์ด ์์๋๋ฐ, ์ด๋ ๊ฒ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ ์์ฒด๊ฐ ์ํ ์ฐธ์กฐ์ ์ํ์ฑ์ ๋ดํฌํ๊ณ ์๋ ํ์์๋ค.
์ํ ์ฐธ์กฐ๋ ์ํํธ์จ์ด ์ค๊ณ์์ ํผํด์ผ ํ๋ ๋ํ์ ์ธ ์ํฐํจํด์ด๋ค.
์ํ ์ฐธ์กฐ์ ๋ฌธ์ ์
์์ SOLID ๊ธ์์ ์ํ ์ฐธ์กฐ๋ ์์กด์ฑ ์ ์ด ๋ฌธ์ ๋ฅผ ๊ฐ์ง๊ณ ์์๋ค. ์ด์ธ์๋ ์ฌ๋ฌ๊ฐ์ง ๋ฌธ์ ์ ์ด ์๋ค.
๋ฌดํ ๋ฃจํ
์๋ก ์๋ฐฉํฅ ์ฐธ์กฐ๋ฅผ ํ๊ณ ์์ผ๋ฉด ์๋ก์ ๋ฉ์๋๋ฅผ ํธ์ถํ ์ ์๋๋ฐ, ์ด๋ ๋ฌดํ ๋ฃจํ์ ๋น ์ง๊ฒ ๋๋ค. ๊ทผ๋ฐ, ์ด๋ ๊ฒ ๊ฐ๋จํ ๋ฌธ์ ๋ฉด ๊ฐ๋ฐ์๊ฐ ์กฐ์ฌํ๋ฉด ๋ ๊ฑฐ ๊ฐ๋ค. ๊ทธ๋ฌ๋ ์์์น ๋ชปํ ๊ณณ์์ ๋ฐ์ํ๊ธฐ๋ ํ๋ค.
Team developerGroup = new Team(1, "developerGroup", new ArrayList<>());
developerGroup.getMembers().add(new Member(1, "foobar", developerGroup));
developerGroup.getMembers().add(new Member(2, "helloworld", developerGroup));
ObjectMapper objectMapper = new ObjectMapper();
String result = objectMapper.writeValueAsString(developerGroup);
System.out.println(result);
์์ ์์ ๋ ์๊น ์ํธ ์ฐธ์กฐ๊ฐ ์๋ Team๊ณผ Member ๊ฐ์ฒด๋ฅผ ํ์ฉํ ์์ ์ด๋ค. Team ๊ฐ์ฒด๋ Member ๊ฐ์ฒด๋ฅผ ๋ฃ์ด JSON ๋ฌธ์์ด๋ก ๋ณํํ๋ค.
Team, Member๋ ์๋ก ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ์ฝ๋๋ ์์์๋ ๋ฌดํ๋ฃจํ๋ฅผ ๋ง๋ค์ด ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค.
์์คํ ๋ณต์ก๋
์กฐ๊ธ ๋ ์ค๋ฌด์ ์ธ ๋ฌธ์ .
‘ํ ๋ด ๋ชจ๋ ํ์๋ค์ ์๊ธ์ ํฉ์ฐํด๋ฌ๋ผ!’ ๋ผ๋ ์๊ตฌ์ฌํญ์ด ์์ ๋ ์๋์ ๊ฐ์ด ์ฝ๋๋ฅผ ์์ฑํ ์๋ ์๊ฒ ๋๋ ๋ฌธ์
@Data
class Team {
private long id;
private String name;
private List<Member> members;
}
@Data
class Member {
private long id;
private String name;
private Team myTeam;
private int salary;
// ํ๋ด ๋๊ตฐ๊ฐ ํ์ ๋ชจ๋์ ์๊ธ์ ์ ๊ทผํ๋ค.
// ,,?
public int calculateTeamMemberTotalSalary() {
int result = 0;
for (Member member : myTeam.getMembers()) {
result += member.salary;
}
return result;
}
์ด๋ฌํ ์ํ ์ฐธ์กฐ๋ก ์ธํ ๋
ผ๋ฆฌ์ ์ค๋ฅ๋ ์ํ ์ฐธ์กฐ๋ฅผ ์์ ์ ํด๊ฒฐํ ์ ์๋ค.
// --- case 1
@Data
class Team {
private long id;
private String name;
private List<Member> members;
}
@Data
class Member {
private long id;
private String name;
private long myTeam;
private int salary;
}
// ------------------
// --- case 2
@Data
class Team {
private long id;
private String name;
// private List<Member> members;
}
@Data
class Member {
private long id;
private String name;
private Team myTeam;
private int salary;
}
// ------------------
case1๊ณผ case2์ ์ฝ๋๋ฅผ ๋ณด๋ฉด ์๋ก์ ์ํ ์ฐธ์กฐ๋ฅผ ์์ ๋ฒ๋ ธ๋ค. ์ด๋ ๊ฒ ํจ์ผ๋ก case1์ ๊ฒฝ์ฐ ์์ฐ์ค๋ Team ํด๋์ค ๋ด์ ์ ์๊ตฌ์ฌํญ์ ๊ตฌํํด์ผ๊ฒ ๋ค๊ณ ์๊ฐํ๊ฒ ๋๊ณ , case2์ ๊ฒฝ์ฐ๋ Service ๊ฐ์ฒด๋ฅผ ๋์ด ํ๋ณ๋ก Member์ ์ ๊ทผํ์ฌ ๊ฐ๊ฐ ๋ฉค๋ฒ ๋ณ๋ก ๊ธ์ฌ๋ฅผ ๋ฐ์์ฌ ์ ์๋ค.
๊ฐ๋ฅํ ํ ๋๋ฉ์ธ ๋ชจ๋ธ๋ค์ ๋จ์ผ ์ง์ ์ ์ ๋ง๋ค์ด ํ์ํ ๊ฐ์ฒด๊ฐ ์์ ๋ ๋จ๋ฐฉํฅ์ผ๋ก ์ ๊ทผํ๋๋ก ๋ง๋ค์.
๋ฉ๋ชจ๋ฆฌ ๋์ - ๋งํฌ ์ค ์ค์ ์๊ณ ๋ฆฌ์ฆ
๊ฐ์ฒด ์ฐธ์กฐ ํ์๊ฐ 0๋ณด๋ค ํฌ๋ฉด ๊ฐ๋น์ง ์ปฌ๋ ์ ์ด ์ญ์ ๋์์ผ๋ก ์ธ์ํ์ง ๋ชปํด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํ๋ค๊ณ ์ผ๋ฐ์ ์ผ๋ก ์๋ ค์ ธ์๋ค. ํ์ง๋ง, ์ค์ ๋ก๋ ๊ทธ๋ ์ง ์๋ค๊ณ ํ๋ค.
mark-and-sweep ์ด๋ผ๋ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ๋์ํด ๋ฃจํธ ๋ ธ๋(์ ์ญ ๋ณ์, ์คํ ๋ณ์ ๋ฑ)์์ ์ ๊ทผํ์ง ๋ชปํ๋ฉด ์ญ์ ๋์์ผ๋ก ๋ณด๊ณ ์ญ์ ํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ํ ์ฐธ์กฐ ํด๊ฒฐ๋ฒ
ํ์คํ ๋ฐฉ๋ฒ์ ์ํ ์ฐธ์กฐ๋ฅผ ๋ง๋ค์ง ๋ง์.
๋ถํ์ํ ์ฐธ์กฐ ์ ๊ฑฐ - ์๋ฐฉํฅ ์ฐธ์กฐ๊ฐ ๊ผญ ํ์ํ์ง ๊ณ ๋ฏผํ๊ธฐ
@Data
@NoArgsConstructor
@Entity(name = "team")
class TeamJpaEntity {
@Id
private String id;
@Column
private String name;
// ๊ผญ ํ์ํ ์ฝ๋์ผ์ง?
@OneToMany(mappedBy = "myTeam")
private List<MemberJpaEntity> members;
}
@Data
@NoArgsConstructor
@Entity(name = "member")
class MemberJpaEntity {
@Id
private String id;
@Column
private String name;
@ManyToOne
@JoinColumn(name = "my_team_id")
private TeamJpaEntity myTeam;
}
์ด๋ฌํ ์๋ฐฉํฅ ์ฐธ์กฐ๊ฐ ๊ผญ ํ์์๋ค. ์ฌ์ค teamId๋ฅผ ๊ฐ์ง๊ณ member๋ฅผ ์๋ณํ์ฌ ํ ๋ณ ๋ฉค๋ฒ ๋ฆฌ์คํธ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ค.
๊ฐ์ ์ฐธ์กฐ ํ์ฉ - ์ฐธ์กฐ๋ฅผ ์์ ๊ณ ์๋ณ์๋ฅผ ๋์
@Data
@NoArgsConstructor
@Entity(name = "team")
class TeamJpaEntity {
@Id
private String id;
@Column
private String name;
@OneToMany(mappedBy = "myTeam")
private List<MemberJpaEntity> members;
}
@Data
@NoArgsConstructor
@Entity(name = "member")
class MemberJpaEntity {
@Id
private String id;
@Column
private String name;
@ManyToOne
@JoinColumn(name = "my_team_id")
private long myTeamId;
}
์์คํ ๋ณต์ก๋๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ case1, case2 ์ฝ๋์ ์ ์ฌํ๋ค.
๊ณตํต ์ปดํฌ๋ํธ ๋ถ๋ฆฌ - ์ํ ์ฝ๋๋ฅผ ์ถ์ถํด๋ฒ๋ฆฌ์
์์ชฝ ์๋น์ค์ ์๋ ๊ณตํต ๊ธฐ๋ฅ์ ํ๋์ ์ปดํฌ๋ํธ๋ก ๋ถ๋ฆฌํด๋ฒ๋ฆฌ๋ ๊ฒ์ด๋ค. ๊ทธ๋ฆฌ๊ณ ์์ชฝ์ด ๊ณตํต ์ปดํฌ๋ํธ์ ์์กดํ๋๋ก ๋ฐ๊พผ๋ค. ์ด๋ฌํ ๋ฐฉ์์ ํตํด ๋จ์ผ ์ฑ ์ ์์น์ ๋์ฑ ์ค์ํ๊ฒ ๋๋ค.
์ด๋ฒคํธ ๊ธฐ๋ฐ ์์คํ ์ฌ์ฉ - ์ด๋ฒคํธ ํ๋ฅผ ๊ตฌ๋ ํ๋๋ก ์ค๊ณ๋ฅผ ๋ณ๊ฒฝํ์
- ์์คํ ์์ ์ฌ์ฉํ ์ค์ ํ๋ฅผ ๋ง๋ ๋ค.
- ํ์์ ๋ฐ๋ผ ์ปดํฌ๋ํธ๋ค์ด ์ค์ ํ๋ฅผ ๊ตฌ๋ ํ๊ฒ ํ๋ค.
- ์ปดํฌ๋ํธ๋ค์ ์ํ ์ค ๋ค๋ฅธ ์ปดํฌ๋ํธ์ ์์ผ์ผ ํ ์ผ์ด ์์ผ๋ฉด ํ์ ์ด๋ฒคํธ๋ฅผ ๋ฐํํ๋ค.
- ์ด๋ฒคํธ๊ฐ ๋ฐํ๋๋ฉด ํ๋ฅผ ๊ตฌ๋ ํ๊ณ ์๋ ์ปดํฌ๋ํธ๋ค์ด ๋ฐ์ํ๋ค.
- ์ปดํฌ๋ํธ๋ ์ด๋ฒคํธ๋ฅผ ํ์ธํ๊ณ ์์ ์ด ์ฒ๋ฆฌํด์ผ ํ ์ด๋ฒคํธ์ด๋ฉด ์ด๋ฅผ ์ฒ๋ฆฌํ๋ค.
- ์ปดํฌ๋ํธ๋ค์ ์์ ์ด ์ฒ๋ฆฌํ์ง ์์๋ ๋๋ ์ด๋ฒคํธ๋ผ๋ฉด ๋ฌด์ํ๋ค.
์ปดํฌ๋ํธ๋ค์ด ์๋ก ์ํธ ์์กดํ์ง ์๊ณ ์ด๋ฒคํธ๋ก ์ด๋ค์ง๊ฒ ๋ง๋ ๋ค. ์ด๋ฌํ ์ด๋ฒคํธ ๋ฐฉ์์ ์คํ๋ง์ ApplicationEvent, ApplicationEventPublisher, EventListener ๋ก ๊ตฌํํ ์ ์๋ค. ๊ผญ, ์คํ๋ง ์๋์ด๋ ์ค์ํ๋ ํ๋ง ์์ด๋ ๋๋ค.
์ด๋ฌํ ๋ฐฉ์์ ํ๋ก๊ทธ๋๋ฐ์ ์ด๋ฒคํธ ๊ธฐ๋ฐ ํ๋ก๊ทธ๋๋ฐ(EDP; Event-driven Programming)์ด๋ผ๊ณ ํ๋ค.
์๋ฐฉํฅ ๋งคํ
๋๋ฉ์ธ ์ค๊ณ๋ฅผ ํ๋ค๊ฐ ์ด์ฉ ์ ์์ด ๋์ค๋ ์ํ ์ฐธ์กฐ์๋ง ์ฌ์ฉํ์.
๋๋ฉ์ธ ๊ฐ์ฒด, ์์์ฑ ๊ฐ์ฒด๋ฅผ ๋๋์ด ๋๋ฉ์ธ ๊ฐ์ฒด๋ ์ํ ์ฐธ์กฐ๊ฐ ์ด๋ฃจ์ด์ง์ง ์๊ฒํ๊ณ ์์์ฑ ๊ฐ์ฒด๊ฐ ์๋ฐฉํฅ ๋งคํ์ ํ๋ ๊ฒ์ ๋ชจ๋ฒ ์ฌ๋ก๊ฐ ๋ ์ ์์ผ๋ JPA ์ํฐํฐ๋ง ๊ฐ์ง๊ณ ์๋ฐฉํฅ ๋งคํ์ ๋ชจ๋ฒ ์ฌ๋ก๊ฐ ๋๊ธฐ ์ด๋ ต๋ค.
์ํ ์ฐธ์กฐ๋ฅผ ๋ง๋ค์ง ์์ผ๋ฉด ‘์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ’ ๊ฐ์ ๊ฐ๋ ์ด ํ์ ์์ด์ง.
์์ ์์ค์ ์ํ ์ฐธ์กฐ
๊ฐ์ฒด ๊ฐ ์ํ ์ฐธ์กฐ๋ฅผ ๋์ด ํจํค์ง, ์์คํ ์์ค์ ์ํ ์ฐธ์กฐ๋ ๋ ํฐ ๋ฌธ์ ๋ค.
API ์์คํ ์ ์ง์ ์์กดํ ์ํฉ, ์์คํ ์ ์ง์ ํธ์ถํ๋ ์ํฉ, ํจํค์ง๊ฐ ๋ ๋ฆฝ์ด์ง ๋ชปํ ์ํฉ ๋ฑ ์ํ ์ฐธ์กฐ๋ฅผ ํผํ์.
'๊ฐ๋ฐ์์ > ์๋ฐ-์คํ๋ง ์ค์ฉ์ฃผ์ ํ๋ก๊ทธ๋๋ฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
04. SOLID (0) | 2025.01.19 |
---|