Programming

[지식 한 입] Java는 웹 개발을 목적으로 개발된 언어가 아니었다

물에빠진사람 2024. 6. 24. 00:41
반응형

 

 

Java는 백엔드를 지망하면 Java를 배우라는 말이 있을 정도로 대한민국에서 대표적인 백엔드 언어로 자리 잡았지만 자바는 사실 웹 개발을 목적으로 개발된 언어가 아니었다.

 

📜 Java의 전신 Oak

자바의 시작은 Oak(오크)라는 이름으로 시작되었습니다. Oak는 제임스 고슬링이 임베디드 시스템 개발을 목적으로 개발한 언어입니다.

 

프로그래밍을 할 때, 만드는 프로그램이 어떤 하드웨어 아키텍처인지, 어떤 운영체제에서 돌아가는지 알아야 합니다. 예를 들어, x86 아키텍처와 ARM 아키텍처는 명령어 세트가 다르고 동일한 프로그램이라도 서로 다른 기계어로 컴파일이 되고, C언어에서 Unix/Linus운영체제에서의 long 데이터 타입은 8바이트이지만, 윈도우에서는 4바이트이듯 하드웨어, 운영체제의 차이에 따라 개발하는 차이가 존재하게 됩니다.

 

이를 해결하기 위해서 만들어진 게  Oak시절에는 바이트코드, Java에서는 JVM입니다. 바이트코드는 플랫폼에 독립적인 중간 코드로, 다양한 하드웨어와 운영체제에서 동일하게 실행될 수 있도록 해줍니다. 자바에서는 JVM이 이 바이트코드를 실행하여, "한 번 작성하면 어디서나 실행된다(Write Once, Run Anywhere)"라는 자바의 슬로건을 실현하고 있습니다.

 

JVM의 등장 덕분에 자바 개발자는 개발 환경에 대한 고민을 덜 수 있게 되었습니다.

 

📜 Java

지금의 Java는 이런 플랫폼 독립성이라는 강점을 가지고 있지만, 과거 하드웨어의 발전 이전에는 이 장점이 오히려 단점으로 작용하기도 했습니다.

플로피 디스크(한글, 워드 등에서 파일 저장의 뜻으로 사용되고 있다.

 

현재는 거의 사용되지 않는 플로피 디스크는 2000년대 초반까지 흔하게 사용되었습니다. 놀랍게도 이 디스크의 용량은 100KB(킬로바이트)에서 1MB (메가바이트) 정도로 매우 적었습니다. 우리가 흔하게 접하는 유튜브 1080p 해상도의 동영상 파일은 1분에 약 100MB이고 휴대폰으로 찍은 고해상도 이미지 파일은 1MB 정도입니다.

 

과거 개발자들은 저러한 환경에서 작게는 KB, 많아도 몇 MB 정도 크기의 개발을 했습니다.

이러한 상황에서 Java를 사용하기 위해 추가로 JVM을 설치해야 한다는 것은 불필요한 용량 투자가 필요하다는 인식이 있을 수밖에 없었고 심지어 Java는 컴파일러 언어인 C언어나 C++처럼 소스코드를 기계어로 직접 컴파일링 하지 않고 바이트코드로 컴파일시킨 후 JVM을 통해 해석 단계를 거치기 때문에 속도 측면에서도 빠르지 않았다. 이는 Java가 초기에는 널리 사용되지 못한 이유 중 하나였습니다.

 

그러나 인터넷과 네트워크의 발전, 그리고 하드웨어 성능의 비약적인 향상으로 인해 Java는 큰 성장을 이루게 되었습니다. 2023년, 세계 최대의 개발자 커뮤니티인 Stack Overflow에서 조사한 바에 따르면 Java는 세계적으로 가장 많이 사용되는 프로그래밍 언어 중 하나로, 백엔드 개발 언어로는 JavaScript와 Python에 이어 3위에 위치해 있습니다.

 

 

📜 객체지향

과거 프로그래밍은 절차적 프로그래밍 방식으로 진행되었다.

대표적으로 C언어가 절차지향적 프로그래밍 언어로 유명한데 절차적 프로그래밍이란 작성된 소스코드를 위에서부터 아래로 순서대로 실행되는 걸 의미한다. 기본적으로 위에서 아래로 읽히다 코드이다 보니 이해가 쉽고 배우는데 어려움이 덜하다. 무엇보다 디버깅할 때 편리하다.

하지만 절차지향적 프로그래밍은 프로젝트의 규모가 커질수록 데이터와 함수가 분리되어 있어 캡슐화하는데 어려움이 생기고 코드가 길어지면서 중복 호출이 반복이 되면서 스파게티 코드로 이어질 가능성이 높다. 이렇게 코드가 꼬여버리게 되면 다른 사람이 유지보수 하는 건 불가능에 가깝고 만든 사람이라고 하더라도 유지보수 하는데 어려움을 겪을 것이다.

 

흔히 농담으로 스파게티 코드는 아예 다시 짜는 게 났다고 하는데 사실 진심으로 하는 농담이다...

 

📜 객체지향적 프로그래밍

절차지향적 프로그래밍의 중복되는 코드, 스파게티 코드가 될 위험성, 모듈화의 어려움 등의 이유로 인해 객체지향적 프로그래밍이 등장하게 되었다.

 

객체지향 프로그래밍이란 데이터와 데이터를 처리하는 메서드를 객체라는 단위로 묶어 프로그램을 설계하고 구현하는 프로그래밍이다. 구체적인 사물, 혹은 사람과 같은 것 혹은 추상적인 개념 등 실제로 현실 세계에 있는 것들을 모델링할 때 절차지향적 프로그래밍보다 강점을 보인다.

 

가령 붕어빵을 예로 만들어보자면 절차지향 프로그래밍에서는,

1. 반죽 만들기 : 밀가루, 물, 설탕을 섞어 반죽을 만든다.

2. 붕어빵 틀에 반죽 붓기 : 만들어진 반죽을 붕어빵 틀에 붓는다.

3. 속 넣기 : 틀에 부어 놓은 반죽 위에 속(팥 혹은 슈크림)을 넣는다.

4. 붕어빵 굽기 : 붕어빵 틀을 닫고 붕어빵을 굽는다.

5. 붕어빵 완성 : 구워진 붕어빵을 틀에서 꺼낸다.

 

이런 식으로 진행될 것이다. 하지만 객체지향 프로그래밍에서는, 자바로 예시를 들어보자면, 붕어빵 클래스를 먼저 정의할 것이다.

public class 붕어빵 {
	private String 속;
    
    public 붕어빵(String 속) {
    	this.속 = 속;
    }
    
    public void 굽기() {
    	붕어빵을 굽는다;
    }
    
    public void set속넣기(String 속) {
    	this.속 = 속;
    }
    
    public void 반죽만들기() {
    	반죽 만들기;
    }
}
public class Main {
    public static void main(String[] args) {
        붕어빵 붕어빵 = new 붕어빵("팥");
        붕어빵.반죽만들기();
        붕어빵.set속넣기("팥");
        붕어빵.굽기();
    }
}

 

단순히 보면 큰 차이를 느낄 수 없지만, 객체지향 프로그래밍은 유지보수와 확장성이 상대적으로 높고 복잡한 시스템을 더 효율적으로 관리할 수 있게 합니다. 가령 예를들어 붕어빵 말고 국화빵을 추가하려한다면 객체지향에서는, 

public class 붕어빵 {
    private String 속;
    private String 종류;   // 새롭게 틀 모양 추가
    
    // 종류에 붕어빵, 국화빵 등의 종류를 입력받는다.
    public 붕어빵(String 속, String 종류) {
    	this.속 = 속;
        this.종류 = 종류;
    }
    
    public void 굽기() {
    	붕어빵을 굽는다;
    }
    
    public void set속넣기(String 속) {
    	this.속 = 속;
    }
    
    public void 반죽만들기() {
    	반죽 만들기;
    }
}

 

간단하게 한줄 추가로 수정이 가능하지만, 절차지향에서는 데이터와 메소드 분리가 잘 되지 않아서 수정하기가 힘들 수 있고, 반복적인 함수 실행이 늘어날 것이다.

반응형