☕JAVA/🐣 강의 [JAVA]

[JAVA][기초] 함수형 프로그래밍 / 중첩클래스

디카페인라떼 2022. 11. 12. 02:39

[기초] 시리즈는 본강의를 수강후 정리한 글들 입니다.

Java for Beginner - YouTube

 

Java for Beginner

[교재 link] https://github.com/namoosori/java-for-beginner/tree/master/doc Java for Beginner 강의에서 다루는 내용은 다음과 같습니다. - Java 개요 : Java 언어가 어떤 언어이고 Java 언어를 이용해 프...

www.youtube.com


💡함수형 프로그래밍의 이해 

  • 함수형 프로그래밍을 이해하기 위해서는 우선 명령형 imperative 프로그래밍과 선언형 declarative 프로그래밍에 대한 이해가 필요
    • 명령형 프로그래밍 : 특정 기능을 수행하기 위해 어떻게 에 집중하는 방식
    • 선언형 프로그래밍 : 특정 기능을 수행하기 위해 무엇에 집중하는 방식

 

  •  함수형 프로그래밍은 선언형 프로그래밍을 따르는 대표적인 프로그래밍 패러다임.
  •  함수형 프로그래밍은 함수들의 집합으로 프로그램을 구성하는 것을 의미
  •  자바에 함수형 프로그래밍 도입은 프로그램 구현 방식에 큰 변화
  •  함수형 프로그래밍의 함수는 순수 함수, 일급 객체, 불변의 자료구조 혹은 영속 자료구조 등과 같은 특성을 가짐. 
    => 어떻게 적용되어 있는지 보는 게 중요

💡예제

  • 고객 리스트 검색하기
    • 요구사항 1 ) 지역명으로 검색하기
    • 추가 요구사항 2) 성별로 검색하기
//요구사항 1) 지역으로 검색
public List<Customer> searchCustomersByLocation (String location){
  List <Customer> foundCustomers = new ArrayList<>();
  for (Customer customer : customers){
    if (customer.getlocation().equals(location)){
      foundCustomers.add(customer);
    }
  }
  return foundCustomers;
}

 

  • 구현 방법 1) 요구 사항이 추가 될 때마다 새로운 메소드 계속 생성하기
 //추가 요구사항 2) 성별로 검색
 public List<Customer> searchCustomersByLocation (String location){
    List <Customer> foundCustomers = new ArrayList<>();
    for (Customer customer : customers){
      if (customer.getGender().equals(gender)){
        foundCustomers.add(customer);
      }
    }
    return foundCustomers;
  }

 


  • 구현 방법 2) 중복되는 코드를 하나의 메소드로 합치고 요구사항이 추가될 때마다 조건문만 추가해주기 
//방법2 : 하나의 메소드로
  public List<Customer> searchCustomersBy (SearchOption searchOption, String searchValue) {
    List<Customer> foundCustomers = new ArrayList<>();
    for (Customer customer : customers) {
      if(searchOption.equals(searchOption.Location)) {
        if (customer.getlocation().equals(location)) {
          foundCustomers.add(customer);
        }
      }else if (searchOption.equals(searchOption.Gender)) {
        if (customer.getGender().equals(gender)) {
          foundCustomers.add(customer);
        }
      }
    }
    return foundCustomers;
  }

 


 

  • 구현방법 3) 인터페이스를 만들어서 중첩클래스로 넣어 서비스단 메소드는 그대로 두고 컨트롤러단에서 검색조건만 바꿔주기

 [ interface 추가 ]

public interface SearchFilter{
  boolean isMatched(Customer customer);
}

[ Service ]

public List<Customer> searchCustomers (SearchFilter filter){
  List<Customer> foundCustomers = new ArrayList<>();
  for (Customer customer : customers) {
    if (filter.isMatched(customer)){
      foundCustomers.add(customer);
    }
  }
  return foundCustomers;
}

 

[ Controller ]

List<Customer> result = new ArrayList<>();
result = service.searchCustomers(new Searchfilter() {
@Override
public boolean isMatched(Customer customer){
    if (customer.getLocation().equals("Seoul")){ // 여기에 조건을 추가해서도 가능.람다보다 가독성이 적음.
      retuen true;
    }else{
      return false;
    }
}
});

 

 

👉@override 된 부분이 클래스 안의 클래스. 중첩클래스 !

 

📌 Lamda 식을 사용하면 좀더 가독성을 높일 수 있음!!

// 람다적용
result = service.searchCustomers( customer -> customer.gerGender().equals(Gender.Male));

📌세밀한 조건도 가능! 동시에 가독성도 높음.

result = service.searchCustomers( customer -> customer.gerGender().equals("Seoul") && customer.getAge() >25);

🚩 결론

  • 함수형 프로그래밍을 사용하면 검색조건이 변경되더라도 서비스단에서 메소드를 추가하거나 검색조건을 추가하지 않아도 된다 ! (메소드 하나로 충분)
  • 검색조건을 매개변수로 보내주고 그걸로 검색을 해서 결과를 출력함.
  • 즉, 코드의 요구사항이 바뀌어서 리팩토링을 해야 할 때 함수형 프로그래밍을 적용하여서 어떻게 리팩토링 해야 하는지 아는 게 중요  

💡중첩클래스

  • 클래스 안에 클래스를 선언 하는 것
    • Static class
      •  Inner class가 static이 붙은 것
    •  Non-Static class : Inner class에 static이 붙지 않은 것
      • member class : 클래스의 정의를 해당 클래스 내부 필드 메소드 단위에 선언한 경우 , Outer class가 객체화 되어야지만 사용 가능
      • local class : 클래스 내의 메소드 안에 선언한 클래스 => 해당 메소드가 호출되었을 때만 사용 가능
      • anonnymus class 익명 클래스 => 클래스의 메소드 안에 있으나 그 순간에만 사용되는 익명의 클래스 / 메소드 안에 클래스의 정의를 넣음