Tutorial#2バックエンド開発


2.バックエンド開発


1. Domain


ビジネスニーズに応じてドメインを指定します.データベースで管理するマスター
この例では、회원ドメインを使用します.
public class Member {
	private Long id;
    private String name;
    
    // getter & setter
}

2. Repository


データベースにアクセスする役割=ドメインオブジェクトを格納/管理する役割

(option) interface


if. DB選択Xまたはメモリ上でテストが必要
インタフェースとして宣言し、使用するためにインプリメンテーションクラスを変更するように設計されています.
// DB or memory 로 접근할 구현 클래스에서 참조할 함수 선언
public interface MemberRepository {
	Member save(Member member);
    Optional<Member> findById(Long id);
    Optional<Member> findByName(String name);
    List<Member> findAll();
}

(option) Access to memory


DBが選択され、すぐにスクリプトが作成されると、データベース接続とクエリーの主体になります.
次の例では、データベースではなくメモリにデータをロードします.
public class MemoryMemberRepository implements MemberRepository {
	private static Map<Long, Member> store = new HashMap<>();
    private static long sequence = 0L;
    
    // = DB에서 member 추가
    @Override
    public Member save(Member member) {
    	member.setId(++sequence);			// DB 상에서 serial 과 동일
        store.put(member.getId(), member);	// DB에 insert
        return member;
    }
    
    // = DB에서 id 조회
    @Override
    public Optional<Member> findById(Long id){
    	return Optional.ofNullable(store.get(id));
    }
    
    // = DB에서 name 조회
    @Override
    public Optional<Member> findByName(String name) {
    	return Optional.ofNullable(store.get(name));
    }
    
    // = DB에서 Member 모두 조회
    @Override
    public List<Member> findAll() {
    	return new ArrayList<>(store.values());
    }
    
    public void clearStore() {
    	store.clear();
    }
}

3. Service


ビジネスロジックの実装部分
つまり、データベースからデータをインポートして任意の操作を実行し、新しいタスクを作成し、データベースのマスターに保存するためにリポジトリに送信します.
public class MemberService {
	private final MemberRepository memberRepository = new MemoryMemberRepository();	//  interface <- implements (DB or Memory)
    
    public Long join(Member member) {
    	validateDuplicateMember(member);
        memberRepositry.save(member);
        return member.getId();
    }
    
    // 중복 회원 조회
    private void validateDuplicateMember(Member member) {
    	memberRepository.findByName(member.getName())
        	.ifPresent(m -> {
            	throw new IllegalStateException(message);
            }
    }
    
    public Optional<Member> findOne(Long memberId) {
    	return memberRepository.findById(memberId);
    }
    
    public List<Member> findMembers(){
    	return memberRepository.findAll();
    }
}

4. Test


テストコードを作成して方法をテストできます.このときは@Test Annotitatonと書きます.また、@AfterEach@BeforeEach等を用いて、試験前後の運転方法を指定することもできる.
// MemberServiceTest
class MemberServiceTest {
	MemberService memberService;
    MemoryMemberRepository memberRepository;
    
    @BeforeEach
    public void beforeEach(){
    	// DI : 의존성 주입
        // 위에서 작성한 코드대로면 테스트할 때 참조하는 repository와 실제 repository는 다른 메모리 위치에 존재하는 객체다. 따라서, 같은 객체를 참조하면서 테스트를 진행하기 위해서는 다음과 같이 코드를 작성하여 테스트할 수 있다. 이때 memberService의 constructor가 memberRepository를 참조하기 때문에 DI가 발생한다.
    	memberRepositry = new MemoryMemberRepository();
        memberService = new MemberService(memberRepository);
    }
    
    @AfterEach
    public void afterEach(){
    	memberRepository.clearStore(); // test data가 중복되어 발생되는 문제를 해결하고자 할때
    }

5. ETC


サービス、レポート、およびコントローラの注釈は、内部に@Component注釈がある.Springコンテナはそれをスキャンし、各コンポーネントを1つのオブジェクトと見なしてbeanを生成します.defaultはsingletoneを生成します.
容器は、各構成要素を接続する際に、@Autowired注釈によって自動的に接続される.もちろんconfigファイルを作成し、@Bean annotationで直接設定することもできます.
🛠 更新を続行する必要があります!
2022.03.18首
2022.03.19 ETC部分を追加