이벤트 종류 4가지

 

-일회성 이벤트

  생일, 식사약속, 회의 등

 

-기간이 지정된 이벤트

  시험기간, 축제기간 등

  시작일과 종료일이 있는 경우

 

-데드라인이 있는 이벤트

  시작일은 없고 데드라인이 있는 일 

  제출기한이 있는 과제, 종료일이 있는 프로젝트 등 

 

-------------------------------------위의 3종류 이벤트기능 개발 예정-------------------------------------------------

 

-주기적 이벤트

  수업시간 등

 


 

1. 이벤트 추가 기능 종류별 3가지

2. 모든 이벤트를 출력하는 기능

3. 특정 날짜에 걸치는 이벤트들을 출력해주는 기능

 

package chapter3;

import java.util.Scanner;

public class Scheduller {
	
	public Event[] events = new Event[100];
	int n1=0;
	
	public void processCommand() {
		
		Scanner kb = new Scanner(System.in);
		while(true) {
			System.out.print("$ ");
			String command = kb.next();
			if(command.equals("addevent")) {
				
			}
			else if(command.equals("list")) {
				
			}
			else if(command.equals("show")) {
				
			}
			else if(command.equals("exit")) {
				break;
			}
				
		}
		kb.close();
	}

	public static void main(String[] args) {
		
		Scheduller app = new Scheduller();
		app.processCommand();
		
	}

}

메인 함수가 있는 클래스 

기본 틀만 구현하였다!

 

package chapter3;

public class Event {
	public String title;
	
	public Event(String title) {
		this.title = title;
	}
}

 

이벤트 클래스

 

package chapter3;

public class MyDate {
	public int year;
	public int month;
	public int day;
	
	public MyDate(int y,int m, int d) {
		year = y;
		month = m;
		day = d;
	}
	public String toString(){
		return year + "/" + month + "/" +day;
	}
}

데이트 클래스(날짜)

 

package chapter3;

public class OnedayEvent extends Event {
	public String title;
	public MyDate date;
	
	public OnedayEvent(String title, MyDate date) {
		super(title);
		this.title = title;
		this.date = date;
	}
	
	public String toString() {
		return title+ ", "+date.toString();  
	}
}

일회성 이벤트 클래스

 

package chapter3;

public class DurationEvent extends Event {

	public MyDate begin;
	public MyDate end;
	
	public DurationEvent(String title, MyDate b, MyDate e) {
		super(title);
		begin =b;
		end = e;
	}
	public String toString() {
		return title+", "+begin.toString()+"~"+end.toString();
	}
}

기간이 있는 이벤트 클래스

 

package chapter3;

public class DeadLineEvent extends Event {
	public MyDate date;
	
	public DeadLineEvent(String title, MyDate date) {
		super(title);
		this.date = date;
	}
	
	public String toString() {
		return title+","+date.toString();
	}
}

데드라인이 있는 이벤트 클래스

구현을 하였다.

 

세부적인 메인부분과 추가해줘야 할 부분에 대해서 다음 포스트에 포스팅 할 예정이다.

'알고리즘 with 자바 > 자료구조' 카테고리의 다른 글

추상클래스와 인터페이스 1  (0) 2021.07.07
클래스 object와 Wrapper 클래스  (0) 2021.07.06
상속 3  (0) 2021.06.30
상속 2  (0) 2021.06.29
상속 1  (0) 2021.06.29

다형성: Polymorphism

 

객체지향 에서 가장 중요한 개념으로써

수퍼클래스 타입의 변수가 서브클래스 타입의 객체를 참조할 수 있다.!

 

Computer theComputuer = new Notebook()

컴퓨터 타입의 변수 theComputer가 Notebook 타입의 객체를 참조하고있다.

그것이 문법적 오류가 아니라는것!

 

왜 이런 규칙을 허용을할까???

실제로 어떤 의미를 가지는것일까?

 

Computer 클래스

Notebook 클래스 

두 클래스모두 toString()이라는 메서드를 가지고 있다.(오버라이딩)

 

Computer test = new Notebook("Dell","15",4,1000,3.2,15.6,1.2);
System.out.println(test.toString());

메인함수에서 

이렇게 한다면 어떤 메서드가 호출될까?

 

두가지 의견이 있을 수 있다.

1. test라는 변수는 Computer 형식이니까 Computer의 toString()이 호출되어야 마땅하다.

  이것은 정적바인딩이라고 한다.

 

2. 어찌되었건 실제 객체로 가리키게 되는것은 Notebook형식이기에 Notebook의 toString()이 호출되어야 마땅하다.

  이것은 동적바인딩이라고 한다.

 

자바에서는 항상 동적 바인딩을 하기때문에 2번 의견이 맞다!

 

'알고리즘 with 자바 > 자료구조' 카테고리의 다른 글

클래스 object와 Wrapper 클래스  (0) 2021.07.06
스케줄러 프로그램  (0) 2021.07.01
상속 2  (0) 2021.06.29
상속 1  (0) 2021.06.29
static 그리고 public 2  (0) 2021.06.28

스프링 부트와 JPA만 사용해도 개발 생산성 증가하고 코드들이 확 줄어든다.

여기에 스프링 데이터 JPA를 사용하면, 기존의 한계를 넘어 마치 마법처럼, 인터페이스 만으로

개발을 완료할 수 있다. 그리고 반복 개발해온 CRUD 기능도 스프링 데이터 JPA가 모두 제공한다.

 

package hello.hellospring.repository;

import hello.hellospring.domain.Member;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface SpringDataJpaMemberRepository extends JpaRepository<Member, Long>, MemberRepository{

    @Override
    Optional<Member> findByName(String name);
}

SpringDataJpaMemberRepository라는 인터페이스를 만든다!

JpaRepository<Member,Long>, MemberRepository를 상속받는다.

 

???구현이 필요가없다???

구현체를 만들어서 스프링데이터JPA가 등록을 해준다..!

 

package hello.hellospring;

import hello.hellospring.repository.*;
import hello.hellospring.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SpringConfig {

    private final MemberRepository memberRepository;

    @Autowired
    public SpringConfig(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    @Bean
    public MemberService memberService(){
        return new MemberService(memberRepository);
    }
}

private fianl MemberRepository memberRepository를 인젝션 받으면

스프링 데이터 JPA가 만들어준 구현체가 등록이된다.

그리고 MemberService()에 의존관계 세팅을 해준다.

 

위의 인터페이스를 만들고 JpaRepository를 상속받으면 스프링 데이터JPA가 

인터페이스에 대한 구현체를 만들어내고 스프링빈에 등록을한다.

 

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/lecture/49598?tab=note

JpaRepository내부에 보면 지금까지 만들었던 기능을 다 가지고있다.

 

만들지 못하는것이 있다. 

공통으로 할 수 없는것들!! 

findByName()이라고 하면 

select m from Member m where m.name = ? 

 이런식으로 JPQL을 짜준다 

 

실무에서는 동적 쿼리는 Querydsl이라는 라이브러리를 사용하면 된다.

이로써 대단원의 막을 내렸다!

 

H2 설치부터

순수 JDBC의 어마어마한 코드,

스프링 통합 테스트,

스프링 JdbcTemplate은 반복되는 코드가 줄어들지만 쿼리를 직접 작성해줘야만 했다.

JPA는 쿼리를 사용할 필요가없지만 JPQL이라는 것을 작성해줘야했고

스프링 데이터 JPA는 내가 할게없이 모든걸 가능하게 해주었다..

'웹프로그래밍 > Spring 입문' 카테고리의 다른 글

22. AOP 적용  (0) 2021.07.01
21. AOP  (0) 2021.07.01
19. JPA  (0) 2021.06.30
18. 스프링 JDBC Template  (0) 2021.06.29
17. 스프링 통합 테스트  (0) 2021.06.29

JPA에 대하여 알아보았다.

 

JDBC로도 해보았고 JDBCTemplate으로 전 포스팅에서 경험해보았다.

JDBCTemplate만 써도 개발해야할 코드가 확 줄어드는것을 확인할 수 있었다.

하지만 SQL query부분은 직접 써줘야만 했다.

 

그런데 JPA라는 기술을 사용하면 SQL query도 자동으로 해주게되어 

개발 생산성을 크게 높일 수 있게된다.

단순히 SQL query을 만들어주는 것을 넘어서서 

SQL과 데이터중심의 설계에서 객체중심의 설계로 패러다임을 전환을 할 수 있다.

 

구글 트렌드에서 Mybatis와 JPA를 비교해서 보면 

2015년 부터 꾸준한 성장을 볼 수 있다!!

국내에도 JPA가 많이 보급되었다고한다.

전세계적으로 보면 JPA가 Mybatis와 비교도 할 수 없을만큼

차이가 심하다.

 

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	runtimeOnly 'com.h2database:h2'
	testImplementation('org.springframework.boot:spring-boot-starter-test') {
	exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' 
	}
}

먼저 JPA를 쓰기위해서는 build.gradle에 라이브러리를 추가해준다.!

 

spring.datasource.url=jdbc:h2:tcp://localhost/~/test 
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none

application.properties에 JPA관련 설정을 추가해준다.

spring.jpa.show-sql을 true를 사용하면 JPA가 날리는 SQL을 볼 수있다.

spring.jpa.hibernate.ddl-auto를 사용하면 JPA가 객체를 보고 

테이블도 만들어주게 된다 하지만 현재 만들어져있고 만들어진 것을 쓸 것이기때문에

none으로 설정해준다.

package hello.hellospring.domain;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Member {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

 

JPA를 쓰려면 엔티티를 매핑해주어야한다.

JPA라는 것은 표준 인터페이스이다. 구현체로 하이버네이트 등등이 있는데

하이버네이트를 쓸 것이다. JPA는 객체와 ORM이라는 기술이다.

 

@Entity 애너테이션을 주면 JPA가 관리하는 엔티티가 된다.

그리고 pk를 설정해준다. 

쿼리에 id를 넣는 것이 아니라 db가 자동으로 id를 생성해주는것을

Identity 전략이라고 한다. 

 

이러한 애너테이션을 가지고 매핑을 하게된다!

 

package hello.hellospring.repository;

import hello.hellospring.domain.Member;

import javax.persistence.EntityManager;
import java.util.List;
import java.util.Optional;

public class JpaMemberRepository implements  MemberRepository{

    private final EntityManager em;

    public JpaMemberRepository(EntityManager em){
        this.em =em;
    }

    @Override
    public Member save(Member member) {
        em.persist(member);
        return member;
    }

    @Override
    public Optional<Member> findById(Long id) {
       Member member = em.find(Member.class, id);
        return Optional.ofNullable(member);
    }

    @Override
    public Optional<Member> findByName(String name) {
        List<Member> result = em.createQuery("select m from Member where m.name= :name", Member.class)
                .setParameter("name",name)
                .getResultList();
        
        return result.stream().findAny();
    }

    @Override
    public List<Member> findAll() {
        return em.createQuery("select m from Member m",Member.class)
        .getResultList();
    }
}

 

JpaMemberRepository를 만들고 MemberRepository를 implements 한다.

JPA는 EntityManger라는 것으로 동작을한다.

스프링부트가 자동으로 EntityManager을 생성해준다.

db랑 통신하는 것들을 처리한다.

findByName이나 findAll을 하려면 JPQL이라는 쿼리를 이용해야한다.

JPQL이란 객체를 대상으로 쿼리를 날리는 것이다.

 

단건을 찾는것은 가능하지만 

pk기반이 아닌 다른 기능들은 JPQL이라는 것이 필요하다.

 

그리고 MemberService클래스에 @Transaction을 필요로하기때문에

걸어둔다!

 

package hello.hellospring;

import hello.hellospring.repository.*;
import hello.hellospring.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.persistence.EntityManager;
import javax.sql.DataSource;

@Configuration
public class SpringConfig {

   private EntityManager em;

   @Autowired
   public SpringConfig(EntityManager em){
       this.em = em;
   }
    @Bean
    public MemberService memberService(){
        return new MemberService(memberRepository());
    }

    @Bean
    public MemberRepository memberRepository(){
        //return new JdbcTemplateMemberRepository(dataSource);
        return new JpaMemberRepository(em);
    }
}

SpringConfig또한 수정해주어야한다.  

EntityManager라는 것이 필요하다.

 

콘솔창에서 뜬 쿼리이다.

Hibernate: select member0_.id as id1_0_, member0_.name as name2_0_ from member member0_ where member0_.name=?
Hibernate: insert into member (id, name) values (null, ?)

 

 

 

'웹프로그래밍 > Spring 입문' 카테고리의 다른 글

21. AOP  (0) 2021.07.01
20. 스프링 데이터 JPA  (0) 2021.06.30
18. 스프링 JDBC Template  (0) 2021.06.29
17. 스프링 통합 테스트  (0) 2021.06.29
16. 순수 JDBC  (0) 2021.06.24

Method Overriding

 

부모로 부터 물려받은 메서드를 재정의 하는것!

(같은 이름의 메서드)

 

package chapter3;

public class Computer {
	private String manufacturer;
	private String processor;
	private int ramSize;
	private int diskSize;
	private double processorSpeed;
	
	public Computer(String man,String proc,int ram,int disk,double procSpeed) {
		manufacturer = man;
		processor = proc;
		ramSize = ram;
		diskSize = disk;
		processorSpeed = procSpeed;
	}
	
	public double computePower() {
		return ramSize * processorSpeed;
	}
	public double getRamSize() {
		return ramSize;
	}
	public double getProcessorSpeed() {
		return processorSpeed;
	}
	public int getDistSize() {
		return diskSize;
	}
	
	public String toString() {
		String result = "manufacturer: " + manufacturer +
				"\nprocessor: " + processor +
				"\nramSize: " + ramSize +
				"\ndiskSize: " + diskSize +
				"\nprocessorSpeed: " + processorSpeed;
		return result;
	}
}

 

Computer 클래스의 toString() 메서드를 

Notebook클래스에서 재정의하고 싶다!

 

package chapter3;

public class Notebook extends Computer {
	
	public double screenSize;
	public double weight;
	
	public Notebook(String man,String proc, int ram, int disk, double speed, double screen, double weight){
		super(man,proc,ram,disk,speed);
	
		screenSize = screen;
		this.weight = weight;
	}
	public String toString() {
		String result = 
				super.toString()+
				"\nscreenSize: " + screenSize+
				"\nweight: " + weight;
		return result;
	}

	public static void main(String[] args) {
		Notebook test = new Notebook("Dell","15",4,1000,3.2,15.6,1.2);
		
		System.out.println(test.toString());

	}

}

Computer 클래스의 멤버가 private 이기때문에 직접 액세스 할 수 가없기에

super.toString()을 불러왔다.

만약 protect 접근제어자 였다면 직접 액세스가 가능하게 된다.!

'알고리즘 with 자바 > 자료구조' 카테고리의 다른 글

스케줄러 프로그램  (0) 2021.07.01
상속 3  (0) 2021.06.30
상속 1  (0) 2021.06.29
static 그리고 public 2  (0) 2021.06.28
static 그리고 public 1  (0) 2021.06.28

내가 기존에 어떤 클래스를 만들어 가지고 있는데

이 클래스와 밀접한 관련이 있는 새로운 클래스를 만들때

IS-A관계!!를 만들 필요가 있다고 한다면

(사람 - 학생) , (컴퓨터 - 노트북) ...

기존 클래스에 있는 멤버들이 모두 필요로 하고 

멤버들을 추가해서 사용하고 싶을때 사용한다!

 

Super class(부모)

Sub class(자식)

 


 

상속과 생성자

 

생성자가 없을 경우 자동으로 no-parameter 생성자가 만들어진다.

생성자가 하나라도 있을 경우 자동으로 만들어지지 않는다.

 

모든 서브 클래스의 생성자는 먼저 수퍼클래스의 생성자를 호출한다.

   1. super()를 통해 명시적으로 호출해 주거나,

   2. 그렇지 않을경우에는 자동으로 no-parameter 생성자가 호출된다.

 

흔한오류 :

   수퍼클래스에 no-parameter 생성자가 없는데, 서브클래스의 생성자에서 

   super() 호출을 안해주는 경우

 

package chapter3;

public class Computer {
	public String manufacturer;
	public String processor;
	public int ramSize;
	public int diskSize;
	public double processorSpeed;
	
	public Computer(String man,String proc,int ram,int disk,double procSpeed) {
		manufacturer = man;
		processor = proc;
		ramSize = ram;
		diskSize = disk;
		processorSpeed = procSpeed;
	}
	
	public double computePower() {
		return ramSize * processorSpeed;
	}
	public double getRamSize() {
		return ramSize;
	}
	public double getProcessorSpeed() {
		return processorSpeed;
	}
	public int getDistSize() {
		return diskSize;
	}
}

수퍼클래스

 

package chapter3;

public class Notebook extends Computer {
	
	public double screenSize;
	public double weight;
	
	public Notebook(String man,String proc, int ram, int disk, double speed, double screen, double weight){
		super(man,proc,ram,disk,speed);
	
		screenSize = screen;
		this.weight = weight;
	}

	public static void main(String[] args) {
		Notebook test = new Notebook("Dell","15",4,1000,3.2,15.6,1.2);
		

	}

}

서브클래스

'알고리즘 with 자바 > 자료구조' 카테고리의 다른 글

상속 3  (0) 2021.06.30
상속 2  (0) 2021.06.29
static 그리고 public 2  (0) 2021.06.28
static 그리고 public 1  (0) 2021.06.28
메서드와 생성자 3  (0) 2021.06.24

JdbcTemplate을 사용하여 db연동을 하여 테스트를 돌려보았다.

 

스프링 JdbcTemplateMyBatis 같은 라이브러리는

JDBC API에서 본 반복 코드를 대부분 제거해준다.

하지만 SQL은 직접 작생해야 한다.

 

package hello.hellospring.repository;

import hello.hellospring.domain.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;

import javax.sql.DataSource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

public class JdbcTemplateMemberRepository implements MemberRepository{

    private final JdbcTemplate jdbcTemplate;

    @Autowired //  생성자 하나기에 생략가능
    public JdbcTemplateMemberRepository(DataSource dataSource){
        jdbcTemplate = new JdbcTemplate(dataSource);
    }

    @Override
    public Member save(Member member) {
        SimpleJdbcInsert jdbcInsert = new SimpleJdbcInsert(jdbcTemplate);
        jdbcInsert.withTableName("member").usingGeneratedKeyColumns("id");

        Map<String,Object> parameters = new HashMap();
        parameters.put("name",member.getName());

        Number Key = jdbcInsert.executeAndReturnKey(new MapSqlParameterSource(parameters));
        member.setId(Key.longValue());
        return member;
    }

    @Override
    public Optional<Member> findById(Long id) {
        List<Member> result = jdbcTemplate.query("select * from member where id =?",memberRowMapper() , id);
        return result.stream().findAny();
    }

    @Override
    public Optional<Member> findByName(String name) {
        List<Member> result = jdbcTemplate.query("select * from member where name =?",memberRowMapper(),name);
        return result.stream().findAny();
    }

    @Override
    public List<Member> findAll() {
        return jdbcTemplate.query("select*from member",memberRowMapper());
    }

    private RowMapper<Member> memberRowMapper(){
        return (rs, rowNum) -> {
            Member member = new Member();
            member.setId(rs.getLong("id"));
            member.setName(rs.getString("name"));
            return member;
        };
    }
}
package hello.hellospring;

import hello.hellospring.repository.JdbcMemberRepository;
import hello.hellospring.repository.JdbcTemplateMemberRepository;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
import hello.hellospring.service.MemberService;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration
public class SpringConfig {

    private DataSource dataSource;

    public SpringConfig(DataSource dataSource){
        this.dataSource = dataSource;
    }

    @Bean
    public MemberService memberService(){
        return new MemberService(memberRepository());
    }

    @Bean
    public MemberRepository memberRepository(){
        return new JdbcTemplateMemberRepository(dataSource);
    }
}

SpringConfig의 memberRepository()에서

repository/JdbcTemplateMemberRepository(dataSource)를 

반환하여 테스트를 돌려보았더니

성공하였다!

정보처리기사 공부하며 나온 디자인 패턴이라는 내용에

깊이있게 들어가고 싶어졌다. 저번시간에도 그렇고 Template패턴이라는 것이

나오고 또한 Singleton패턴이라는 말도 자주 나온다

다음에 꼭 디자인패턴쪽도 공부해보아야 겠다!

'웹프로그래밍 > Spring 입문' 카테고리의 다른 글

20. 스프링 데이터 JPA  (0) 2021.06.30
19. JPA  (0) 2021.06.30
17. 스프링 통합 테스트  (0) 2021.06.29
16. 순수 JDBC  (0) 2021.06.24
15. H2 데이터베이스 설치  (0) 2021.06.24

저번에 진행했던 테스트 들은 스프링과 관련없는 자바코드 테스트 였다!!

이번에는 스프링과 관련지어  테스트를 해보았다!

 

package hello.hellospring.repository;

import hello.hellospring.domain.Member;
import hello.hellospring.service.MemberService;
import org.junit.jupiter.api.*;
import hello.hellospring.domain.Member;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
@Transactional
public class MemberServiceIntegrationTest {

        @Autowired MemberService memberService;
        @Autowired MemberRepository memberRepository;

        @Test
        void 회원가입() {
            //given
            Member member = new Member();
            member.setName("hello");
            //when
            Long saveId = memberService.join(member);
            //then
            Member findMember = memberService.findOne(saveId).get();
            Assertions.assertThat(member.getName()).isEqualTo(findMember.getName());
        }

        @Test
        public void 중복_회원_예외() {
            //given
            Member member1 = new Member();
            member1.setName("Spring");

            Member member2 = new Member();
            member2.setName("Spring");

            //when
            memberService.join(member1);
            IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));

            Assertions.assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다");

        }

        @Test
        void findMembers() {
        }

        @Test
        void findOne() {
        }
    }

 

@Transactional 애너테이션 을 주게되면

테스트 시작 전에 트랜잭션을 실행하고 완료 후

 롤백을 하게된다. 이렇게되면 DB에 데이터가 남기에 다음테스트에

영향을 줄 수 없다!

그렇기에 지난 테스트 코드의 @Before @After가 필요없게 되었다!

 

@SpringBootTest 애너테이션을 주게되면 

스프링 컨테이너와 테스트를 함께 실행한다.

 

그렇다면? 전에 작성했던 코드는 의미가 없는것이 아닐까?

답은 아니다. 

순수하게 자바코드로 최소한의 단위로 테스트 하는것을

단위테스트

 

스프링,컨테이너까지 같이 테스트하는 것은 

통합테스트

 

단위 테스트가 좋은 테스트일 확률이 높기때문에 

단위테스트를 잘만들어야 좋은 테스트라고 할 수 있다.!

'웹프로그래밍 > Spring 입문' 카테고리의 다른 글

19. JPA  (0) 2021.06.30
18. 스프링 JDBC Template  (0) 2021.06.29
16. 순수 JDBC  (0) 2021.06.24
15. H2 데이터베이스 설치  (0) 2021.06.24
14. 회원 웹 기능 - 조회  (0) 2021.06.24

접근제어

 

public : 클래스 외부에서 접근이 가능하다.

 

private : 클래스 내부에서만 접근이 가능하다.

 

default : 동일 패키지에 있는 다른 클래스에서 접근 가능하다.

 

protected : 동일 패키지의 다른 클래스와 다른 패키지의 하위클래스에서도 접근 가능하다.

 


 

데이터 캡슐화

 

모든 데이터 멤버를 private으로 만들고 필요한 경우에 public한 get/set 메서드를 제공한다.

 

이렇게 하면 객체가 제공해주는 메서드를 통하지 않고서는 객체 내부의 데이터에 접근할 수가 없다.

 

이것은 data encapsulation혹은 information hiding이라고 부른다.

 


 

앞서 나왔던 프로젝트에 데이터필드와 메서드를 알맞은 지정자를 지정한 후

getter setter를 이용해 보았다.

 

package section2;

public class Term3 {
	
	private int coef;//계수
	private int exp;//차수
	
	public Term3(int c, int e) {
		coef = c;
		exp = e;
	}
	
	public int calTerm(int x) {
		return (int)(coef * Math.pow(x, exp));
	}
	
	public void printTerm() {
		System.out.print(coef + "x^" +exp);
	}
	public int getCoef() {
		return coef;
	}
	public void setCoef(int coef) {
		this.coef = coef;
	}
	public int getExp() {
		return exp;
	}
}
package section2;

public class Polynomial3 {
	
	private char name; //다항식의 이름
	private int nTerms = 0; // 항의 개수
	private Term3[] terms; //항들의 배열
	
	public Polynomial3() {
		nTerms=0;
		terms = new Term3[100];
	}
	
	public Polynomial3(char name) {
		this.name = name;
		nTerms=0;
		terms = new Term3[100];
	}
	
	public char getName() {
		return name;
	}
	
	public int calcPolynomial(int x) {
		int result = 0;
		
		for (int i =0; i< nTerms; i++) {
			result += (terms[i].calTerm(x));
			}
		return result;
	}

	public void printPolynomial() {
		for(int i =0; i<nTerms; i++) {
			terms[i].printTerm();
			System.out.print("+");
		}
		System.out.println();
		
	}
	
	public void addTerm(int c, int e) {
		int index = findTerm(e);
		if(index != -1) {
				terms[index].setCoef(terms[index].getCoef() + c);
		}
		else {
			int i = nTerms-1;
			while(i >= 0 && terms[i].getExp() < e) {
				terms[i+1] = terms[i];
				i--;
			}
			terms[i+1] = new Term3(c,e);
			nTerms++;
		}
	}

	private int findTerm(int e) {
		for(int i=0;i<nTerms && terms[i].getExp() >= e;i++) {
			if(terms[i].getExp() ==e) {
				return i;
			}
		}
		return -1;
	}
}
package section2;

import java.util.Scanner;

public class code11{

	Polynomial3 polys[] = new Polynomial3 [100];
	int n = 0;
	
	public void procesCommand() {
		Scanner kb = new Scanner(System.in);
		while(true) {
			System.out.print("$ ");
			String command = kb.next();
			if(command.equals("create")) {
				char name = kb.next().charAt(0);
				polys[n] = new Polynomial3(name);
				n++;
			}
			else if(command.equals("add")) {
				char name = kb.next().charAt(0);
				int index = find(name);
				if(index==-1) {
					System.out.println("No such Polynomial exist");
				}
				else {
					int c = kb.nextInt();
					int e = kb.nextInt();
					polys[index].addTerm(c,e);
					
				}
				
			}
			else if(command.equals("calc")) {
				char name = kb.next().charAt(0);
				int index = find(name);
				if(index==-1) {
					System.out.println("No such Polynomial exist");
				}
				else {
					int x = kb.nextInt();
					int result = polys[index].calcPolynomial(x);
					System.out.println(result);
				}
				
			}
			else if(command.equals("print")) {
				char name = kb.next().charAt(0);
				int index = find(name);
				if(index==-1) {
					System.out.println("No such Polynomial exist");
				}
				else {
					polys[index].printPolynomial();
				}

			}
			else if(command.equals("exit")) {
				break;
			}
		}
		
		kb.close();

	}
	public static void main(String[] args) {
		
		code11 app = new code11();
		app.procesCommand();

	}

	private int find(char name) {
		for(int i =0;i<n;i++) {
			if(polys[i].getName() == name) {
				return i;
			}
		}
		return -1;
	}

}

 

'알고리즘 with 자바 > 자료구조' 카테고리의 다른 글

상속 2  (0) 2021.06.29
상속 1  (0) 2021.06.29
static 그리고 public 1  (0) 2021.06.28
메서드와 생성자 3  (0) 2021.06.24
메서드와 생성자 2  (0) 2021.06.24

클래스는 타입이다. 집이 아니라 집의 설계도이다. 즉 실체가 아니다!

 

따라서 클래스의 데이터 필드에 데이터를 저장할 수는 없고, 클래스의 

멤버 메서드를 실행할 수 도 없다. 왜냐하면 실체가 아니기 때문

 

new 명령으로 해당 클래스의 객체를 만든 후 , 그 객체에 데이터를 저장하고,

그 객체의 멤버 메서드를 실행하는 것이다. 

 

여기에는 하나의 예외가 존재하는데 그것이 static 멤버이다.

static 멤버는 클래스 안에 실제로 존재하며 객체에는 존재하지 않는다.

 

 그렇다면?

 

왜 메인 메서드는 반드시 static이어야 하는가?

   자바에서는 프로그램이란 클래스의 집합이다. 이 클래스라는건 설계도일뿐!

   그렇기에 static이어야 한다. main이라는 것은 시작점이기에 누군가 new로 만들어줄 수 없기때문이다.

 

왜 static 메서드에서 같은 클래스의 non-static 멤버를 액세스할 수 없는가?

   메인 함수가 포함된 클래스에서는 이때까지 static변수를 사용하였다. static메서드는 클래스 메서드이다.

   그렇기에 static멤버만 액세스가 가능!

 

다른 클래스에 속한 static 멤버는 어떻게 액세스 하는가?

   static멤버는 클래스이름.static멤버 이런식으로 액세스한다.

 

static 메서드/필드의 용도는?

   1. static의 필수적인 경우는 메인 메서드이다.

   2. 상수, 혹은 클래스 당 하나만 유지하고 있으면 되는값

   3. 순수하게 기능만으로 정의되는 메서드, 대표적인 예로는 수학 함수들.

 

앞에서 작성했던 다항식 프로그램들을 main메서드만이 static이 되도록 수정해보았다!

 

package section2;

import java.util.Scanner;

public class code11{

	Polynomial3 polys[] = new Polynomial3 [100];
	int n = 0;
	
	public void procesCommand() {
		Scanner kb = new Scanner(System.in);
		while(true) {
			System.out.print("$ ");
			String command = kb.next();
			if(command.equals("create")) {
				char name = kb.next().charAt(0);
				polys[n] = new Polynomial3(name);
				n++;
			}
			else if(command.equals("add")) {
				char name = kb.next().charAt(0);
				int index = find(name);
				if(index==-1) {
					System.out.println("No such Polynomial exist");
				}
				else {
					int c = kb.nextInt();
					int e = kb.nextInt();
					polys[index].addTerm(c,e);
					
				}
				
			}
			else if(command.equals("calc")) {
				char name = kb.next().charAt(0);
				int index = find(name);
				if(index==-1) {
					System.out.println("No such Polynomial exist");
				}
				else {
					int x = kb.nextInt();
					int result = polys[index].calcPolynomial(x);
					System.out.println(result);
				}
				
			}
			else if(command.equals("print")) {
				char name = kb.next().charAt(0);
				int index = find(name);
				if(index==-1) {
					System.out.println("No such Polynomial exist");
				}
				else {
					polys[index].printPolynomial();
				}

			}
			else if(command.equals("exit")) {
				break;
			}
		}
		
		kb.close();

	}
	public static void main(String[] args) {
		
		code11 app = new code11();
		app.procesCommand();

	}

	private int find(char name) {
		for(int i =0;i<n;i++) {
			if(polys[i].name == name) {
				return i;
			}
		}
		return -1;
	}

}

 

 

'알고리즘 with 자바 > 자료구조' 카테고리의 다른 글

상속 1  (0) 2021.06.29
static 그리고 public 2  (0) 2021.06.28
메서드와 생성자 3  (0) 2021.06.24
메서드와 생성자 2  (0) 2021.06.24
메서드와 생성자 1  (0) 2021.06.23

+ Recent posts