[오늘의 코딩테스트]
[프로그래머스/JS] 콜라 문제
- 문제- 코드function solution(a, b, n) { var answer = 0; while(n >= a) { answer += Math.floor(n/a)*b n = Math.floor(n / a) * b + n % a; } return answer;}-해설우선 n을 a개로 나누는 것이 목적이기 때문에 n이 a개만큼 더 못나누는
ezez99.tistory.com
[오늘의 한일]
● Layered Architecture Pattern
● 테스트 코드
● 게임서버 프로그래머의 이해
● Layered Architecture Pattern
계층형 아키텍쳐 패턴을 이용하여서 간단한 응용 코드를 제작하였다.
위의 설계를 기반으로 코드를 작성하였다.
- Controller 코드
// Post의 컨트롤러(Controller)역할을 하는 클래스
export class PostsController {
constructor(postsService){
this.postsService = postsService;
}
getPosts = async (req, res, next) => {
try {
// 서비스 계층에 구현된 findAllPosts 로직을 실행합니다.
const posts = await this.postsService.findAllPosts();
return res.status(200).json({ data: posts });
} catch (err) {
next(err);
}
};
getPostById = async (req, res, next) => {
try {
const { postId } = req.params;
// 서비스 계층에 구현된 findPostById 로직을 실행합니다.
const post = await this.postsService.findPostById(postId);
return res.status(200).json({ data: post });
} catch (err) {
next(err);
}
};
createPost = async (req, res, next) => {
try {
const { nickname, password, title, content } = req.body;
// 서비스 계층에 구현된 createPost 로직을 실행합니다.
const createdPost = await this.postsService.createPost(
nickname,
password,
title,
content,
);
return res.status(201).json({ data: createdPost });
} catch (err) {
next(err);
}
};
updatePost = async (req, res, next) => {
try {
const { postId } = req.params;
const { password, title, content } = req.body;
// 서비스 계층에 구현된 updatePost 로직을 실행합니다.
const updatedPost = await this.postsService.updatePost(
postId,
password,
title,
content,
);
return res.status(200).json({ data: updatedPost });
} catch (err) {
next(err);
}
};
deletePost = async (req, res, next) => {
try {
const { postId } = req.params;
const { password } = req.body;
// 서비스 계층에 구현된 deletePost 로직을 실행합니다.
const deletedPost = await this.postsService.deletePost(postId, password);
return res.status(200).json({ data: deletedPost });
} catch (err) {
next(err);
}
};
}
- Service 코드
export class PostsService {
constructor(postsRepository){
this.postsRepository = postsRepository;
}
findAllPosts = async () => {
// 저장소(Repository)에게 데이터를 요청합니다.
const posts = await this.postsRepository.findAllPosts();
// 호출한 Post들을 가장 최신 게시글 부터 정렬합니다.
posts.sort((a, b) => {
return b.createdAt - a.createdAt;
});
// 비즈니스 로직을 수행한 후 사용자에게 보여줄 데이터를 가공합니다.
return posts.map((post) => {
return {
postId: post.postId,
nickname: post.nickname,
title: post.title,
createdAt: post.createdAt,
updatedAt: post.updatedAt,
};
});
};
findPostById = async (postId) => {
// 저장소(Repository)에게 특정 게시글 하나를 요청합니다.
const post = await this.postsRepository.findPostById(postId);
return {
postId: post.postId,
nickname: post.nickname,
title: post.title,
content: post.content,
createdAt: post.createdAt,
updatedAt: post.updatedAt,
};
};
createPost = async (nickname, password, title, content) => {
// 저장소(Repository)에게 데이터를 요청합니다.
const createdPost = await this.postsRepository.createPost(
nickname,
password,
title,
content,
);
// 비즈니스 로직을 수행한 후 사용자에게 보여줄 데이터를 가공합니다.
return {
postId: createdPost.postId,
nickname: createdPost.nickname,
title: createdPost.title,
content: createdPost.content,
createdAt: createdPost.createdAt,
updatedAt: createdPost.updatedAt,
};
};
updatePost = async (postId, password, title, content) => {
// 저장소(Repository)에게 특정 게시글 하나를 요청합니다.
const post = await this.postsRepository.findPostById(postId);
if (!post) throw new Error('존재하지 않는 게시글입니다.');
// 저장소(Repository)에게 데이터 수정을 요청합니다.
await this.postsRepository.updatePost(postId, password, title, content);
// 변경된 데이터를 조회합니다.
const updatedPost = await this.postsRepository.findPostById(postId);
return {
postId: updatedPost.postId,
nickname: updatedPost.nickname,
title: updatedPost.title,
content: updatedPost.content,
createdAt: updatedPost.createdAt,
updatedAt: updatedPost.updatedAt,
};
};
deletePost = async (postId, password) => {
// 저장소(Repository)에게 특정 게시글 하나를 요청합니다.
const post = await this.postsRepository.findPostById(postId);
if (!post) throw new Error('존재하지 않는 게시글입니다.');
// 저장소(Repository)에게 데이터 삭제를 요청합니다.
await this.postsRepository.deletePost(postId, password);
return {
postId: post.postId,
nickname: post.nickname,
title: post.title,
content: post.content,
createdAt: post.createdAt,
updatedAt: post.updatedAt,
};
};
}
- Repository 영역
export class PostsRepository {
constructor(prisma){
this.prisma = prisma;
}
findAllPosts = async () => {
// ORM인 Prisma에서 Posts 모델의 findMany 메서드를 사용해 데이터를 요청합니다.
const posts = await this.prisma.posts.findMany();
return posts;
};
findPostById = async (postId) => {
// ORM인 Prisma에서 Posts 모델의 findUnique 메서드를 사용해 데이터를 요청합니다.
const post = await this.prisma.posts.findUnique({
where: { postId: +postId },
});
return post;
};
createPost = async (nickname, password, title, content) => {
// ORM인 Prisma에서 Posts 모델의 create 메서드를 사용해 데이터를 요청합니다.
const createdPost = await this.prisma.posts.create({
data: {
nickname,
password,
title,
content,
},
});
return createdPost;
};
updatePost = async (postId, password, title, content) => {
// ORM인 Prisma에서 Posts 모델의 update 메서드를 사용해 데이터를 수정합니다.
const updatedPost = await this.prisma.posts.update({
where: {
postId: +postId,
password: password,
},
data: {
title,
content,
},
});
return updatedPost;
};
deletePost = async (postId, password) => {
// ORM인 Prisma에서 Posts 모델의 delete 메서드를 사용해 데이터를 삭제합니다.
const deletedPost = await this.prisma.posts.delete({
where: {
postId: +postId,
password: password,
},
});
return deletedPost;
};
}
다음과 같은 3개의 영역으로 코드를 나눠서 계층형 아키펙터모델로 코드를 만들어보았다.
● 테스트 코드
테스트 코드를 통해서 데이터의 대한 결과 값을 예상하여 미리 테스트 값을 알아보는 코드를 배워보았다.
// validation.js
export const isEmail = (value) => {
const email = (value || '');
if (email.split('@').length !== 2) {
return false;
} else if (email.includes(' ')) {
return false;
} else if (email[0] === '-') {
return false;
}
return true;
};
다음과 같은 테스트를 통해서 해당 테스트한 결과 값이 올바르게 나왔는지 확인을 할 수 있다.
● 게임서버 프로그래머의 이해
게임서버 프로그래머의 역할이나 게임이 어떤식으로 제작이 되어가는지에 대해 학습하였다.
초기 팀구성은 3명의 PD,AD, TD가 기획을 짜면서 게임제작을 시작한다.
- PD or 기획팀에 의한 게임에 대한 전반적인 내용 정리
- 시나리오, 장르, 방향성 문서 정리
- 아트팀 → 컨셉 아트 등 이미지 제작 이후 내부 공개
- 팀 구성 시작 (클라이언트 위주 개발)
위와 같이 PD가 우선 전반적인 시나리오, 장르, 방향성등을 정하고, 아트팀이 해당하는 컨셉의 아트를 제작한다음 해당 아트를 기반으로 TD가 초기 게임모델 클라이언트를 제작한다.
이때 서버가 하는역할은 크게 없다라고 생각하면 된다.
- 인프라 구성
- 대규모 트래픽처리를 위한 분산 서버 구성
- 업데이트 방식 설계
- 서버 관리, 모니터링 툴 적용
- NAS, 내부망, 클라우드 세팅
- 팀원 모집
- 인프라, 클라우드, DBA, 웹, 게임서버
- 서버 로직 개발
- 오픈 컨텐츠 개발 대응
- 더미테스트, 부하테스트
- 내, 외부 QA 대응
위와 같은 역할을 진행하지만 본격적으로 서버가 활동하는 시기는 오픈초기라고 한다.
오픈을 하고 진행을 하면 검정과 검증이 필요하다
예시)
유저가 1번 아이템을 사용할 시 HP 100이 회복되어야 하는 경우
- 검증
- 1번 아이템이 DB 혹은 게임 에셋에 존재하는지 확인합니다.
- 실제로 HP 100이 증가하는지 확인합니다.
- 아이템이 존재하지 않거나 기대한 기능을 수행하지 못할 시 버그(이슈)로 간주
- 검정 (확인)
- 실제 플레이어들이 접속하는 환경에서 1번 아이템이 실제로 100의 HP를 회복시켜주는지 확인
- 사용자 경험과 관련
[한줄평]
학습을 마무리한 날이다. 오늘까지 열심히 했으니깐 내일부터는 이학습을 기반으로 열심히 개인과제를 진행하여야겠다.
'코딩 > TIL' 카테고리의 다른 글
[TIL/31일차] 개인과제 마무리 (1) | 2024.06.13 |
---|---|
[TIL/30일차] 프로젝트 시작 (0) | 2024.06.13 |
[TIL/28일차] 객체지향, 아키텍쳐 패턴 (0) | 2024.06.10 |
[TIL/27일차] 프로젝트 마무리 (0) | 2024.06.10 |
[TIL/26일차] 팀 프로젝트 진행 - 2 (1) | 2024.06.03 |