Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 17 additions & 29 deletions src/main/java/nextstep/qna/domain/Answer.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,17 @@
package nextstep.qna.domain;

import nextstep.qna.CannotDeleteException;
import nextstep.qna.NotFoundException;
import nextstep.qna.UnAuthorizedException;
import nextstep.users.domain.NsUser;

import java.time.LocalDateTime;

public class Answer {
private Long id;

private NsUser writer;

public class Answer extends BaseEntity {
private Question question;

private NsUser writer;
private String contents;

private boolean deleted = false;

private LocalDateTime createdDate = LocalDateTime.now();

private LocalDateTime updatedDate;

public Answer() {
}

Expand All @@ -29,7 +20,7 @@ public Answer(NsUser writer, Question question, String contents) {
}

public Answer(Long id, NsUser writer, Question question, String contents) {
this.id = id;
super(id);
if(writer == null) {
throw new UnAuthorizedException();
}
Expand All @@ -43,35 +34,32 @@ public Answer(Long id, NsUser writer, Question question, String contents) {
this.contents = contents;
}

public Long getId() {
return id;
}

public Answer setDeleted(boolean deleted) {
this.deleted = deleted;
return this;
}

public boolean isDeleted() {
return deleted;
public void delete(NsUser loginUser) throws CannotDeleteException {
validateDeletableBy(loginUser);
markAsDeleted();
}

public boolean isOwner(NsUser writer) {
return this.writer.equals(writer);
}

public NsUser getWriter() {
return writer;
}

public String getContents() {
return contents;
return this.writer;
}

public void toQuestion(Question question) {
this.question = question;
}

private void validateDeletableBy(NsUser loginUser) throws CannotDeleteException {
if (!isOwner(loginUser)) {
throw new CannotDeleteException("다른 사람이 쓴 답변이 있어 삭제할 수 없습니다.");
}
}
public DeleteHistory createDeleteHistory() {
return new DeleteHistory(ContentType.ANSWER, getId(), getWriter(), LocalDateTime.now());
}

@Override
public String toString() {
return "Answer [id=" + getId() + ", writer=" + writer + ", contents=" + contents + "]";
Expand Down
48 changes: 48 additions & 0 deletions src/main/java/nextstep/qna/domain/Answers.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package nextstep.qna.domain;

import nextstep.qna.CannotDeleteException;
import nextstep.users.domain.NsUser;

import java.util.ArrayList;
import java.util.List;

public class Answers {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

일급 콜렉션 추가 👍

private final List<Answer> answers;

public Answers() {
this(new ArrayList<>());
}

public Answers(Answer answer) {
this(List.of(answer));
}

public Answers(List<Answer> answers) {
this.answers = answers;
}


public List<Answer> getAnswers() {
return this.answers;
}

public void add(Answer answer) {
this.answers.add(answer);
}

public void delete(NsUser loginUser) throws CannotDeleteException {
for (Answer answer : answers) {
answer.delete(loginUser);
}
}

public List<DeleteHistory> createDeleteHistories() {
List<DeleteHistory> deleteHistories = new ArrayList<>();

for (Answer answer : answers) {
deleteHistories.add(answer.createDeleteHistory());
}

return deleteHistories;
}
}
31 changes: 31 additions & 0 deletions src/main/java/nextstep/qna/domain/BaseEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package nextstep.qna.domain;

import java.time.LocalDateTime;

public abstract class BaseEntity {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

private Long id;

private LocalDateTime createdDate = LocalDateTime.now();

private LocalDateTime updatedDate;

private boolean deleted = false;

public BaseEntity() {}

public BaseEntity(Long id) {
this.id = id;
}

public Long getId() {
return id;
}

protected void markAsDeleted() {
this.deleted = true;
}

public boolean isDeleted() {
return deleted;
}
}
23 changes: 23 additions & 0 deletions src/main/java/nextstep/qna/domain/PostContent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package nextstep.qna.domain;

import nextstep.users.domain.NsUser;

public class PostContent {
private final NsUser writer;
private final String title;
private final String contents;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Answer는 title이 없는데 이 객체를 사용해도 될까?
이 객체 또한 분리해야하지 않을까?


public PostContent(NsUser writer, String title, String contents) {
this.writer = writer;
this.title = title;
this.contents = contents;
}

public NsUser getWriter() {
return this.writer;
}

public boolean isOwner(NsUser loginUser) {
return writer.equals(loginUser);
}
}
91 changes: 40 additions & 51 deletions src/main/java/nextstep/qna/domain/Question.java
Original file line number Diff line number Diff line change
@@ -1,66 +1,34 @@
package nextstep.qna.domain;

import nextstep.qna.CannotDeleteException;
import nextstep.users.domain.NsUser;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

public class Question {
private Long id;
public class Question extends BaseEntity {
private PostContent postContent;

private String title;

private String contents;

private NsUser writer;

private List<Answer> answers = new ArrayList<>();

private boolean deleted = false;

private LocalDateTime createdDate = LocalDateTime.now();

private LocalDateTime updatedDate;
private Answers answers = new Answers();

public Question() {
}

public Question(NsUser writer, String title, String contents) {
this(0L, writer, title, contents);
this(0L, new PostContent(writer, title, contents));
}

public Question(Long id, NsUser writer, String title, String contents) {
this.id = id;
this.writer = writer;
this.title = title;
this.contents = contents;
}

public Long getId() {
return id;
}

public String getTitle() {
return title;
this(id, new PostContent(writer, title, contents));
}

public Question setTitle(String title) {
this.title = title;
return this;
}

public String getContents() {
return contents;
}

public Question setContents(String contents) {
this.contents = contents;
return this;
public Question(Long id, PostContent postContent) {
super(id);
this.postContent = postContent;
}

public NsUser getWriter() {
return writer;
return postContent.getWriter();
}

public void addAnswer(Answer answer) {
Expand All @@ -69,24 +37,45 @@ public void addAnswer(Answer answer) {
}

public boolean isOwner(NsUser loginUser) {
return writer.equals(loginUser);
return postContent.isOwner(loginUser);
}

public Question setDeleted(boolean deleted) {
this.deleted = deleted;
return this;
public void markAsDeleted(NsUser loginUser) throws CannotDeleteException {
validateDeletableBy(loginUser);
markAsDeleted();
}

public boolean isDeleted() {
return deleted;
public void delete(NsUser loginUser) throws CannotDeleteException {
this.markAsDeleted(loginUser);
answers.delete(loginUser);
}

public List<DeleteHistory> createDeleteHistories() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

List<DeleteHistory> histories = new ArrayList<>();

histories.add(new DeleteHistory(
ContentType.QUESTION,
getId(),
getWriter(),
LocalDateTime.now()
));

histories.addAll(answers.createDeleteHistories());

return histories;
}

public List<Answer> getAnswers() {
return answers;
public void validateDeletableBy(NsUser loginUser) throws CannotDeleteException {
if (!isOwner(loginUser)) {
throw new CannotDeleteException("질문을 삭제할 권한이 없습니다.");
}
}

@Override
public String toString() {
return "Question [id=" + getId() + ", title=" + title + ", contents=" + contents + ", writer=" + writer + "]";
return "Question{" +
"postContent=" + postContent +
", answers=" + answers +
'}';
}
}
27 changes: 5 additions & 22 deletions src/main/java/nextstep/qna/service/QnAService.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service("qnaService")
Expand All @@ -26,24 +24,9 @@ public class QnAService {
@Transactional
public void deleteQuestion(NsUser loginUser, long questionId) throws CannotDeleteException {
Question question = questionRepository.findById(questionId).orElseThrow(NotFoundException::new);
if (!question.isOwner(loginUser)) {
throw new CannotDeleteException("질문을 삭제할 권한이 없습니다.");
}

List<Answer> answers = question.getAnswers();
for (Answer answer : answers) {
if (!answer.isOwner(loginUser)) {
throw new CannotDeleteException("다른 사람이 쓴 답변이 있어 삭제할 수 없습니다.");
}
}

List<DeleteHistory> deleteHistories = new ArrayList<>();
question.setDeleted(true);
deleteHistories.add(new DeleteHistory(ContentType.QUESTION, questionId, question.getWriter(), LocalDateTime.now()));
for (Answer answer : answers) {
answer.setDeleted(true);
deleteHistories.add(new DeleteHistory(ContentType.ANSWER, answer.getId(), answer.getWriter(), LocalDateTime.now()));
}
deleteHistoryService.saveAll(deleteHistories);

question.delete(loginUser);

deleteHistoryService.saveAll(question.createDeleteHistories());
}
}
}
Loading