응집도 (Cohesion)

응집도는 모듈 내부의 요소들이 서로 얼마나 관련되어 있는지를 측정하는 것입니다

높은 응집도는 모듈 내의 요소들이 서로 긴밀하게 관련되어 있음을 나타내며, 모듈이 한 가지 기능이나 목적을 가지고 있음을 의미합니다

 

높은 응집도는 모듈을 이해하고 유지보수하기 쉽게 만들어줍니다

또한 모듈이 특정 기능에 집중하므로 재사용성이 증가하고 버그를 찾아내기 쉬워집니다

 

결합도 (Coupling)

결합도는 모듈 간의 상호 의존성을 나타냅니다

낮은 결합도는 모듈 간의 의존성이 낮음을 의미하며, 각 모듈이 독립적으로 존재할 수 있다는 것을 나타냅니다

 

서로 다른 모듈 간에 직접적인 데이터 교환 없이 인터페이스를 통해 통신하는 경우, 결합도는 낮다고 볼 수 있습니다

 

낮은 결합도는 모듈 간의 독립성을 증가시켜 변경이나 업그레이드가 쉬워지며, 모듈 간의 오류 전파를 방지합니다

또한, 모듈을 독립적으로 테스트할 수 있게 만듭니다

 

결론

응집도는 모듈 내부의 강도를 특정하고, 결합도는 모듈 간의 상호 의존성을 측정합니다

높은 응집도와 낮은 결합도는 이상적인 상태입니다

모듈은 자체적으로 강하게 구성되어 있으면서 다른 모듈과의 의존성이 최소화되어야 합니다

높은 응집도와 낮은 결합도를 모두 달성하는 것이 이상적입니다

하지만 어떤 경우에는 응집도를 높이기 위해서는 결합도를 어느 정도 희생해야 할 수도 있습니다

 

리다이렉트(Redirect)

리다이렉트는 서버가 클라이언트에게 다른 페이지로 이동하라고 요청하는 방법입니다

리타이렉트는 두 단계로 이루어집니다

 

  1. 클라이언트에게 다른 URL로 이동하라는 응답을 보냅니다
  2. 클라이언트는 새로운 URL로 재요청을 보냅니다

 

리다이렉트는 브라우저에게 새로운 URL로 이동하라는 명령을 주기 때문에, 클라이언트는 서버에게 두 번의 요청을 보냅니다

이로 인해 브라우저의 주소 표시줄이 변경되고, 새로운 페이지로 이동하는 효과를 가집니다

주로 외부 URL로 이동하거나, 현재 요청과 관련 없는 새로운 요청을 처리할 때 사용됩니다

 

<%
	response.sendRedirect("newPage.jsp");
%>

 

포워드(Forward)

포워드는 서버 내에서 페이지 간에 정보를 전달하면서 이동하는 방법입니다

포워드는 단일 요청에 대한 단일 응답을 유지하며, 클라이언트는 이동한 사실을 알 수 없습니다

주로 동일한 웹 어플리케이션 내에서 다른 JSP나 서블릿으로 제어를 이전할 때 사용됩니다

 

<%
	pageContxt.forward("newPage.jsp");
%>

 

리다이렉트(Redirect)와 포워드(Forward)의 차이점

  리다이렉트 포워드
주소 표시줄 변화 주소가 변경됨 주소가 변경되지 않음
클라이언트와 서버 간 통신 두 번의 요청이 발생함 단일 요청과 응답
데이터 공유 쿠키나 세션을 통해 데이터를 공유할 수 있음 요청과 응답 객체를 통해 데이터를 공유함
적합한 사용 시나리오 외부 URL로 이동이나 현재 요청과 무관한 새로운 요청일 때 사용 동일한 애플리케이션 내에서 제어를 이전하거나 데이터를 공유해야 할 때 사용

 

리다이렉트와 포워드는 각각의 특성에 따라 다른 사용 시나리오에 적합하므로, 상황에 따라 적절한 방법을 선택하는 것이 중요합니다

JSP는 동적 웹 페이지를 생성하기 위한 Java 기반의 서버 사이드 템플릿 언어입니다

JSP 페이지 지시어, 스크립트릿, 표현식은 JSP에서 코드를 삽입하고 제어하는 데 사용되는 중요한 구성 요소들입니다

이 글에서는 JSP 페이지 지시어와 함께 스크립트릿과 표현식에 대해 알아보겠습니다

 

JSP 페이지 지시어 (Page Directive)

JSP 페이지 지시어는 페이지의 속성을 설정하고 정의하는 데 사용됩니다

주로 페이지의 언어, 콘텐츠 타입, import할 클래스 등을 정의하는 데 활용됩니다

이를 통해 페이지의 동작을 조절할 수 있습니다

페이지 지시어 예시

 

JSP 스크립트릿 (Scriptlet)

JSP 스크립트릿은 Java 코드를 삽입하는 데 사용됩니다

페이지가 서버에서 실행된 때 이 코드는 동적으로 실행되어 웹 페이지의 내용을 생성합니다

스크립트릿 예시

 

JSP 표현식 (Expression)

JSP 표현식은 페이지에서 값을 출력하는 데 사용됩니다

스크립트릿과 달리 간단한 표현식만을 사용하며, 변수나 계산식 등을 출력할 때 효과적으로 활용됩니다

표현식 예시

 

'==' (동등 연산자)

'=='는 동등 연산자로서 두 값이 동등한지 여부를 판단합니다

그러나 이 연산자는 형 변환을 수행하여 비교하므로 데이터 형식이 다를 경우 자동으로 형 변환이 이루어집니다

 

1 == '1'; // true

 

위의 예제에서는 '1'이라는 문자열과 1이라는 숫자가 서로 다른 데이터 형식이지만 '==' 연산자는 자동으로 형 변환을 수행하여 true를 반환합니다

 

'===' (일치 연산자)

'==='는 일치 연산자로서 값과 데이터 형식이 완전히 일치하는지를 판단합니다

이 연산자는 형 변환을 수행하지 않으므로 데이터 형식이 일치해야만 true를 반환합니다

 

1 === '1'; // false

 

위의 예제에서는 '===' 연산자는 데이터 형식이 다르기 때문에 false를 반환합니다

 

언제 어떤 연산자를 사용해야 하는가?

일반적으로 '==='를 사용하는 것이 권장됩니다

왜냐하면 '==='는 형 변환을 수행하지 않기 때문에 예상치 못한 결과를 방지할 수 있습니다

특히 데이터 형식이 중요한 경우에는 '==='를 사용하여 명시적인 일치를 확인하는 것이 좋습니다

 

그러나 '=='는 특정 상황에서 유용할 수 있습니다

예를 들어, null 또는 undefined 값을 확인할 때 '=='를 사용하면 형 변환이 수행되어 두 값이 동등한지를 판단할 수 있습니다

 

null == undefined; // true;
null === undefined; // false;

 

프로젝트명: 영양제 쇼핑몰

요구사항

1. 회원

- 회원가입 

- 로그인

- 로그아웃

- 회원탈퇴

 

2. 제품

- [관리자] 제품 추가

- [관리자] 제품 삭제

- [관리자] 제품 정보 변경

 

3. 장바구니

- 장바구니 추가

- 장바구니 목록 보기

- 장바구니 담긴 제품 결제

 

4. 구매 내역

- 구매내역 보기

- 결제 취소

- 환불

 

5. 쿠폰

- [관리자] 쿠폰 지급

- 쿠폰 내역 보기

- 구매 시 쿠폰 사용하기

 

6. 리뷰

- 리뷰에 내용과 별점

- 리뷰 목록 보기

- 구매 확정 후 리뷰 쓰기

 

1. 크롤링

크롤링은 웹 페이지를 자동으로 돌며 웹 페이지의 링크를 추출하고, 이를 기반으로 다른 페이지로 이동하면서 데이터를 수집하는 프로세스입니다. 크롤러 또는 스파이더라고 불리는 프로그램이 여러 웹 페이지를 돌며 데이터를 수집하는 것이 크롤링의 핵심입니다

 

2. 스크래핑

스크래핑은 특정 웹 페이지에서 필요한 데이터를 추출하는 과정을 의미합니다. 크롤링으로 얻은 여러 웹 페이지 중에서 스크래핑을 통해 원하는 정보만을 추출하여 활용할 수 있습니다. 스크래핑은 HTML 태그를 분석하고 원하는 데이터를 추출하는 기술을 사용합니다

 

3. 크롤링의 스크래핑의 차이

목적

- 크롤링: 다수의 웹 페이지를 돌며 링크를 추출하고 새로운 페이지로 이동하는 것이 주된 목적입니다

- 스크래핑: 특정 웹 페이지에서 필요한 데이터를 추출하는 것이 주된 목적입니다

 

프로세스

- 크롤링: 여러 웹 페이지를 돌며 링크를 추출하고 새로운 페이지로 이동하여 계속해서 데이터를 수집합니다

- 스크래핑: 특정 웹 페이지의 HTML을 분석하여 원하는 데이터를 추출합니다

 

데이터의 규모 

- 크롤링: 대량의 데이터를 수집하는 데 주로 사용되며, 다양한 웹 페이지를 대상으로 합니다

- 스크래핑: 특정 웹 페이지에서 소량의 데이터를 추출하는 데 주로 사용되며, 목적에 맞게 정확한 정보를 추출합니다

 

기술적 측면

- 크롤링: 링크 추출, 다중 페이지 이동, 로봇 배제 프로토콜 등이 중요한 기술입니다

- 스크래핑: HTML 파싱, 정규표현식, 데이터 추출 알고리즘 등이 중요한 기술입니다

 

제네릭이 없어서 생기는 문제이다

그래서 2번 라인을 문제 발생으로 지적하고 제네릭을 써주는걸 해결 방법으로 답을 적었다

 

하지만 문제는 7번 라인에서 발생한다

원인은 제네릭이 없는 게 맞지만 그로 인해 ArrayList에는 Object 자료형이 저장되어 있는데, 이를 for each문에서 int로 꺼내려고 해서 문제가 발생한다

 

느낀 점

제네릭에 대해 모르고 있는 부분을 확인할 수 있어서 좋았다

프로그래밍 개발은 복잡한 프로세스로, 효과적인 팀 협업과 소프트웨어의 원활한 개발을 위해 다양한 설계서와 명세서가 필요합니다

이 글에서는 주요 설계서와 명세서에 대해 살펴보겠습니다

 

요구사항 명세서

프로젝트의 출발점은 목적과 범위를 정의하는 단계입니다

이를 위해 요구사항 명세서가 사용되며, 프로젝트의 기능과 비기능적 요구사항을 명확히 정의하여 이해관계자 간의 의사소통을 원활하게 합니다

 

시스템 설계서

프로젝트의 구조를 결정하는 시스템 설계서는 시스템 아키텍처, 모듈, 그리고 컴포넌트의 상세 설계를 다룹니다

테이터베이스, 사용자 인터페이스, 시스템 흐름 등이 이 문서에 포함됩니다

 

기능 명세서

각 기능에 대한 세부적인 설명과 동작 방식을 다루는 기능 명세서는 개발자들이 소프트웨어의 각 부분을 구현할 때 참고하는 중요한 문서입니다

 

기술 명세서

기술 명세서는 소프트웨어 개발에 사용되는 기술적인 측면에 대한 세부 사항을 다룹니다

데이터베이스 스키마, 프로그래밍 언어, 프레임워크, 서버 구성 등이 여기에 속합니다

 

테스트 계획서

품질을 보장하기 위한 테스트 전략과 테스트 케이스를 정의하는 테스트 계획서는 시스템이 기대한 대로 동작하는 지 확인하는 데 중요합니다

 

사용자 매뉴얼

사용자를 위한 사용 방법에 대한 지침을 담은 사용자 매뉴얼은 최종 사용자가 소프트웨어를 효과적으로 활용할 수 있도록 도와줍니다

 

유지보수 문서

유지보수를 위한 문서는 코드 구조, 변경 이력, 버그 수정 내역 등을 포함하여 소프트웨어를 지속적으로 개선하는 데 필요한 정보를 제공합니다

 

Mac에 도커로 오라클을 설치한 환경이고 ORA-12505 에러가 발생했다

챗gpt에게 먼저 물어봤다

 

 

나는 2번을 통해 해결했다

 

listener.ora 파일의 위치는 위와 같다

 

 

위에 보이는 2번째 SID_DESC를 추가해줬다

아마도 이클립스를 통해서 제대로 연결했다면 자동으로 xe sid가 생성됐어야는데 그걸 제대로 못해줘서 그런 듯하다

 

이게 원인이 아니었다.. 다른 방법으로 해결함.. 다시 포스팅 할 예정

접근 제어자란?

접근 제어자는 클래스 멤버 (변수, 메서드)의 접근 권한을 제어하는 키워드입니다

Java에서는 크게 네 가지의 접근 제어자가 있습니다

 

  • public: 어떤 클래스에서든 접근 가능
  • protected: 같은 패키지 내에서 그리고 해당 클래스를 상속받은 외부 패키지의 클래스에서 접근 가능
  • default (package-private): 같은 패키지 내에서만 접근 가능 (접근 제어자를 명시하지 않은 경우 기본 값)
  • private: 같은 클래스 내에서만 접근 가능

 

각 접근 제어자의 활용

1. public

 

public class PublicExample {
    public int publicVariable;
    
    public void publicMethod() {
        // 메서드 내용
    }
}

 

다른 패키지의 클래스에서도 접근 가능한 공개된 멤버입니다

 

2. protected

 

public class ProtectedExample {
    protected int protectedVariable;
    
    protected void protectedMethod() {
        // 메서드 내용
    }
}

 

상속 관계에 있는 클래스에서도 접근 가능하며, 같은 패키지에서도 접근 가능합니다

 

3. dafault (package-private)

 

class DefaultExample {
    int defaultVariable;
    
    void defaultMethod() {
        // 메서드 내용
    }
}

 

접근 제어자를 명시하지 않으면 기본적으로 같은 패키지에서만 접근 가능한 멤버가 됩니다

 

4. private

 

public class PrivateExample {
    private int privateVariable;
    
    private void privateMethod() {
        // 메서드 내용
    }
}

 

같은 클래스 내에서만 접근 가능한 멤버로, 외부 클래스에서 직접 접근할 수 없습니다

 

접근 제어자의 선택 기준

적절한 접근 제어자를 선택하는 것은 클래스의 캡슐화를 지원하고 유지보수성을 높이는 데 중요합니다

항상 가장 낮은 접근 권한을 사용하는 것이 좋으며, 필요한 경우에만 더 높은 접근 권한을 허용하는 것이 좋습니다

 

접근 제어자는 프로그램의 보안성과 모듈성을 강화하는 데 중요한 역할을 합니다

올바르게 사용하면 코드의 유지보수성을 향상시킬 수 있습니다

 

Java Doc 주석이란?

Java Doc 주석은 자바 소스 코드에 추가되는 주석의 한 종류로, 코드에 대한 문서를 생성하는 데 사용됩니다

이 주석은 특별한 형식으로 작성되며, 주로 클래스, 메서드, 필드 등의 선언 부분에 위치합니다

Java Doc 주석을 이용하면 코드의 의도와 사용 방법, 관련된 주의사항 등을 명확하게 기술할 수 있습니다

 

Java Doc 주석 작성 방법

Java Doc 주석은 다음과 같은 형식을 따릅니다

 

/**
 * 여기에 주석 내용을 작성합니다.
 * 여러 줄로 작성 가능합니다.
 *
 * @author 작성자
 * @version 버전 정보
 * @param 매개변수명 매개변수 설명
 * @return 반환값 설명
 * @throws 예외타입 예외 설명
 */

 

여기서 `@author`, `@version`, `@param`, `@return`, `@throws` 등은 Java Doc  도구가 이 주석을 분석하여 문서를 생성할 때 사용되는 태그입니다

 

효과적인 Java Doc 주석의 예

/**
 * 계산기 클래스는 기본적인 사칙 연산을 수행합니다.
 * 이 클래스는 두 수를 입력으로 받아 덧셈, 뺄셈, 곱셈, 나눗셈을 수행할 수 있습니다.
 *
 * @author John Doe
 * @version 1.0
 */
public class Calculator {

    /**
     * 주어진 두 수를 더합니다.
     *
     * @param num1 첫 번째 숫자
     * @param num2 두 번째 숫자
     * @return 덧셈 결과
     */
    public int add(int num1, int num2) {
        return num1 + num2;
    }

    /**
     * 주어진 두 수를 뺍니다.
     *
     * @param num1 첫 번째 숫자
     * @param num2 두 번째 숫자
     * @return 뺄셈 결과
     */
    public int subtract(int num1, int num2) {
        return num1 - num2;
    }

    // 곱셈, 나눗셈 메서드에 대한 주석도 추가 가능
}

 

Java Doc 주석은 코드의 가독성을 향상시키고, 문서를 자동으로 생성하여 개발자들이 더 효율적으로 협업할 수 있도록 도와줍니다

주석을 작성할 때는 명확하고 간결하게 정보를 전달하도록 노력하며, 코드를 이해하기 쉽게 만드는 데에 주석이 큰 도움이 됩니다

Java Doc 주석을 적극적으로 활용하여 프로젝트의 유지보수성과 품질을 향상시킬 수 있습니다

객체 지향 프로그래밍의 상속, 캡슐화, 다형성, 추상화,, 들어도 들어도 헷갈려서 정리했습니다

 

상속

상속은 OOP의 중요한 특징 중 하나로, 기존 클래스의 특성을 그대로 이어받아 새로운 클래스를 생성하는 메커니즘입니다

상속을 통해 코드의 재사용성을 높일 수 있고, 코드 중복을 최소화할 수 있습니다

부모 클래스의 속성과 메서드를 자식 클래스가 물려받아 사용할 수 있으며, 자식 클래스에서는 필요에 따라 새로운 기능을 추가하거나 부모 클래스의 기능을 재정의할 수 있습니다

 

class Animal {
    void speak() {
        System.out.println("Animal speaks");
    }
}

class Dog extends Animal {
    void speak() {
        System.out.println("Dog barks");
    }
}

// 사용 예시
Dog myDog = new Dog();
myDog.speak();  // 출력: Dog barks

 

캡슐화

캡슐화는 객체의 상태와 행위를 하나로 묶고, 외부에서의 접근을 제어하는 것을 의미합니다

이는 정보 은닉을 통해 객체의 내부 구현을 외부로부터 숨기고, 오직 정의된 인터페이스를 통해서만 객체와 상호작용할 수 있도록 하는 것입니다

캡슐화는 코드의 모듈성을 높이고, 객체 간의 결합도를 낮춰 시스템을 유연하게 만듭니다

 

class Car {
    private int speed;  // 속성을 비공개로 설정

    int getSpeed() {
        return speed;
    }

    void setSpeed(int newSpeed) {
        if (newSpeed > 0) {
            speed = newSpeed;
        }
    }
}

// 사용 예시
Car myCar = new Car(60);
System.out.println(myCar.getSpeed());  // 출력: 60
myCar.setSpeed(80);
System.out.println(myCar.getSpeed());  // 출력: 80

 

다형성

다형성은 같은 인터페이스를 공유하면서 다양한 구현을 가질 수 있는 능력을 의미합니다

다형성은 코드의 유연성을 향상시키면, 동일한 메서드 호출에 대해 다른 동작을 수행할 수 있도록 합니다

이는 메서드 오버로딩과 메서드 오버라이딩을 통해 구현됩니다

 

abstract class Shape {
    abstract double area();
}

class Circle extends Shape {
    private double radius;

    Circle(double radius) {
        this.radius = radius;
    }

    double area() {
        return 3.14 * radius * radius;
    }
}

class Rectangle extends Shape {
    private double length;
    private double width;

    Rectangle(double length, double width) {
        this.length = length;
        this.width = width;
    }

    double area() {
        return length * width;
    }
}

// 사용 예시
Circle circle = new Circle(5);
Rectangle rectangle = new Rectangle(4, 6);
System.out.println(circle.area());      // 출력: 78.5
System.out.println(rectangle.area());   // 출력: 24

 

추상화

추상화는 복잡한 시스템에서 중요한 부분을 간추려 표현하는 과정입니다

이는 사용자에게 필요한 정보만을 제공하고 나머지는 숨겨짐으로써 시스템을 더 이해하기 쉽게 만듭니다

추상화는 클래스와 인터페이스를 통해 구현되며, 불필요한 세부사항을 숨기고 핵심 기능에만 집중할 수 있도록 도와줍니다

 

abstract class Shape {
    abstract double area();
}

class Circle extends Shape {
    private double radius;

    Circle(double radius) {
        this.radius = radius;
    }

    double area() {
        return 3.14 * radius * radius;
    }
}

class Rectangle extends Shape {
    private double length;
    private double width;

    Rectangle(double length, double width) {
        this.length = length;
        this.width = width;
    }

    double area() {
        return length * width;
    }
}

// 사용 예시
Circle circle = new Circle(5);
Rectangle rectangle = new Rectangle(4, 6);
System.out.println(circle.area());      // 출력: 78.5
System.out.println(rectangle.area());   // 출력: 24

+ Recent posts