2 분 소요

💡 객체 지향 프로그래밍 입문 시리즈

인프런의 객채 지향 프로그래밍 입문을 기반으로 작성한 게시물 입니다.
(본 시리즈의 모든 예시는 JavaScript(TypeScript)로 변환하여 작성하였습니다.)
객체 지향 프로그래밍 입문_1
객체 지향 프로그래밍 입문_2
객체 지향 프로그래밍 입문_3
객체 지향 프로그래밍 입문_4
객체 지향 프로그래밍 입문_5
객체 지향 프로그래밍 입문_6
객체 지향 프로그래밍 입문_7


“추상화 예제”

추상화 예제 1

  • 기능 예시
    • 클라우드 파일 통합 관리 기능 개발
    • 대상 클라우드: 드롭박스, 박스
    • 주요 기능: 각 클라우드 파일 목록 조회, 다운로드, 업로드, 삭제, 검색

추상화 하지 않은 경우

public enum CloudId {
	DROPBOX = 'DROPBOX';
	BOX = 'BOX';
}
public class FileInfo {
    private cloudId: CloudId;
    private fileId: string;
    private name: string;
    private lengh: number;

    //	... get 메서드
}

public class CloudFileManager {
    public getFileInfos(cloudId: CloudId): FileInfo[] {
        if(cloudId === CloudId.DROPBOX) {
            const dc: DropboxClient = ...;
            const dbFiles: DbFile[] = db.getFiles();
            const result: FileInfo[] = [];
            for (var i =0; var < dbFiles.length; i++) {
                const fi: FileInfo = new FileInfo();
                fi.setCloudId(CloudId.DROPBOX);
                fi.setFileId(fi.getFileId);
                ...
                result.push(fi);
            }
            return result;
        } else if(cloudId === CloudId.BOX) {
            const boxSvc: BoxService = ...;
        }
    }
}

public download(file: FileInfo, localTarget: File): void {
    if(file.getCloudId() === CloudId.DROPBOX) {
        const dc: DropboxClient = ...;
        const out: FileOutputStream = new FileOutputStream(localTarget);
        dc.copy(file.getFiledId(), out);
        out.close();
    } else if(file.getCloudId() === CloudId.BOX) {
        const boxSvc: BoxService = ...;
        const is:InputStream = boxSvc.getInputStream(file.getId());
        const out:FileOutputStream = new FileOuptputStream(localTarget);
        CopyUtil.copy(is, out);
    }
}

// 만약 클라우드가 추가 된다면??
public getFileInfos(cloudId: CloudId): Fileinfo[] {
    if(cloudId === CloudId.DROPBOX) {
        ...
    } else if(cloudId === CloudId.BOX) {
        ...
    } else if(cloudId === CloudId.SCLOUD) {
        ...
    } else if(cloudId === CloudId.NCLOUD) {
        ...
    } else if(cloudId === CloudId.DCLOUD) {
        ...
    }
}

이렇게 클라우드 종류가 3개만 추가 되엇을 뿐인데 각 기능에 대한 조건문 분기가 많아지게 되어 코드가 복잡하게 된다.

oop_6_image_1

위의 코드는 클라우드간 파일 복사에 대한 기능을 if else 문만 표기한 것이다.

단순 복사 기능만해도 이렇게 조건문이 많을진데 향후 기능이 다양해 진다면 문제가 더욱 커진다.

이렇듯 추상화가 되지 않는다면 코드 구조가 길어지고 복잡해짐 뿐만 아니라 관련 코드가 여러곳에 분산되며 결과적으로 코드의 가독성과 분석 속도가 저하된다.

최종적으로 서비스가 지속될 수록 개발 시간은 기하급수적으로 늘어나 새로운 기능 추가를 두려워 하게 된다.

추상화 한 코드

public class DropBoxFileSystem implements CloudFileSystem {
    private dbClient: DropBoxClient = new DropBoxClient(...);
	
    public getFiles(): CloudFile[] {
        const dbFiles: DbFile[] = dbClient.getFiles();
        const results: CloudFile[] = new Array(dbFiles.size());
        dbFiles.forEach(file => {
            const cf: DropBoxCloudFIle = new DropBoxCloudFile(file, dbClient);
            results.push(cf);
        })
    }
    return results;
}

// DropBoxCloudFile
public class DropBoxCloudFile implements CloudFile {	
    private dbClient: DropBoxClient;
    private dbFile: DbFile;
    constructor(
        dbClient: DropBoxClient;
        dbFile: DbFile;
    ) {
        this.dbFile = dbFile;
        this.dbClient = dbClient;
    }
    public getId(): string {
        return this.dbFile.getId();		
    }
    public hsUrl(): boolean {
        return true;
    }
    public getUrl(): string {
        return this.dbFile.getFileUrl();
    }
    public getName(): string {
        return this.dbFile.getFileName();		
    }
    public getInputStream(): InputStream {
        return this.dbClient.createStreamOfFile(dbFile);		
    }
    public write(out: OutputStream): void {
        ...
    }
    public delete(): void {
        dbClient.deleteFile(dbFile.getId());
    }
    ...
}

// File info 가져오는 메서드
public getFileInfos(cloudId: CloudId): CloudFile[] {
    const fileSystem: CloudFileSystem = 
        CloudFileSystemFactory.getFileSystem(cloudId);
    return fileSystem.getFiles();
}
public download(file: CloudFile, localTarget: File) {
    file.write(new FileOutputStream(localTarget));
}

oop_6_image_2

oop_6_image_3

// 파일 복사 기능
public copy(file: CloudFile, target: CloudId) {
    // target을 이용해서 각 파일 시스템을 가져온 뒤
    const fileSystem: CloudFileSystem = 
        CloudFileSystemFactory.getFileSystem(target);
    // 각 파일 시스템 내에 있는 copyFrom 함수를 통해 파일을 복사
    fileSystem.copyFrom(file);
}

→ 각 파일 시스템 내의 copyFrom 메서드 예

oop_6_image_4

:point_up: 이렇게 추상화를 하면 추상화한 타입으로만 핵심 기능 구현 가능

oop_6_image_5

:point_up: OCP (Open-Closed Principle, 개방 폐쇠의 원칙)
새로운 클라우드 지원 추가 가능(Open for Extension, 확장에 열려있음) 코드 수정 불필요 (Closed for Modification, 수정엔 닫혀있음)

댓글남기기