[객체 지향 프로그래밍 입문] 5. 추상화 예시
46244 단어 객체 지향 프로그래밍 입문객체 지향 프로그래밍 입문
출처: 최범균님의 객체 지향 프로그래밍 입문 강의
https://www.inflearn.com/course/%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%EC%9E%85%EB%AC%B8/dashboard
기능 예시
- 클라우드 파일 통합 관리 기능 개발
- 대상 클라우드
- 드롭박스, 박스
- 주요 기능
- 각 클라우드의 파일 목록 조회, 다운로드, 업로드, 삭제, 검색
추상화하지 않은 구현
- 파일 목록 조회
public enum CloudId {
DROPBOX,
BOX;
}
public class FileInfo {
private CloudId cloudId;
private String fileId;
private String name;
private long length;
... // get 메서드
}
// 1, 2: 비슷한 부분들
public class CloudFileManager {
public List<FileInfo> getFileInfos(CloudId cloudId) {
if (cloudId == CloudId.DROPBOX) { // 1
// DropboxClient를 이용해서 파일 목록을 가져오고, 이걸 FileInfo로 변환
DropboxClient dc = ...; //
List<DbFile> dbFiles = db.getFiles(); // 2
List<FileInfo> result = new ArrayList<>();
for (DbFile dbFile : dbFiles) {
FileInfo fi = new FileInfo();
fi.setCloudId(CloutId.DROPBOX); // 2
fi.setFileId(fi.getFileId()); // 2
...
result.add(fi);
}
result.add(fi);
} else if (cloutId == CloudId.BOX) { // 1
BoxService boxSvc = ...;
...
}
}
}
- 파일 다운로드
// 1, 2: 비슷한 부분들
public void download(FileInfo file, File localTarget) {
if (file.getCloudId() == CloudId.DROPBOX) { // 1
DropboxClient dc = ...; // 2
FileOutputStream out = new FileOutputStream(localTarget);
dc.copy(file.getFileId(), out); // 2
out.close();
} else if (file.getCloudId() == CloudId.BOX) { // 1
BoxService boxSvc = ...; // 2
InputStream is = boxScv.getInputStream(file.getId()); // 2
FileOutputStream out = new FileOutputStream(localTarget);
CopyUtil.copy(is, out); // 2
}
}
- 기타 기능 추가
public FileInfo upload(File file, CloudId cid) {
if (cid == CloudId.DROPBOX) {
...
} else if (cid == CloudId.BOX) {
...
}
}
public void delete(File file, CloudId cid) {
if (cid == CloudId.DROPBOX) {
...
} else if (cid == CloudId.BOX) {
...
}
}
public List<FileInfo> search(String query, CloudId cid) {
if (cid == CloudId.DROPBOX) {
...
} else if (cid == CloudId.BOX) {
...
}
}
- 이어지는 추가
- 클라우드 추가 (S클라우드, N클라우드, D클라우드)
- 기능 추가 (클라우드 간 파일 복사)
- 클라우드 추가
public class CloudFileManager {
public List<FileInfo> getFileInfos(CloudId cloudId) {
if (cloudId == CloudId.DROPBOX) {
...
} else if (cloutId == CloudId.BOX) {
...
} else if (cloutId == CloudId.SCLOUD) { // 추가
...
} else if (cloutId == CloudId.NCLOUD) { // 추가
...
} else if (cloutId == CloudId.DCLOUD) { // 추가
...
}
}
}
download(), upload(), delete(), search()도 유사한 else-if 블록 추가
- 클라우드 간 복사
public FileInfo copy(FileInfo fileInfo, CloudId to) {
CloudId from = fileInfo.getCloudId();
if (to = CloudId.DROPBOX) {
DropBoxClient dbClient = ...;
if (from =CloudId.BOX) { // 1
dbClient.copyFromUrl("http://www.box.com/files/"+fileInfo.getFileId());
} else if (from = CloudId.SCLOUD) { // 1
ScloudClient sClient = ...;
InputStream is = sClient.getInputStream(fileInfo.getFileId());
dbClient.copyFromInputStream(is, fileInfo.getName());
} else if (from ==CloudId.DCLOUD) { // 1
dbClient.copyFromUrl("http://www.dcloud.com/getfile?fileId=”+fileInfo.getFileId());
} else if (from == CloudId.NCLOUD) { // 1
NCloudClient nClient = ...;
nClient.Save(fileInfo.getFileId(), temp);
InputStream is = new FileInputStream(temp);
dbClient.copyFromInputStream(is, fileInfo.getName());
}
}
if-else만 작성했는데도 복잡
추상화
- 추상화해보면
DROPBOX, BOX, SCLOUD, DCLOUD, NLCOUD => 클라우드 파일 시스템
- 클라우드 파일 시스템 설계
- DROPBOX 구현
public class DropBoxFileSystem implements CloudFileSystem { // CloudFileSystem을 상속
private DropBoxClient dbClient = new DropBoxClient(...);
@Override public List<CloudFile> getFiles() {
// 내부적으로는 DropBoxClient를 이용하여 구현하지만 실제 결과물은 CloudFile을 리턴하는 식으로 구현
List<DbFile> dbFiles = dbClient.getFiles();
List<CloudFile> results = new ArrayList<>(dbFiles.size());
for (DbFile file : dbFiles) {
DropBoxCloudFile cf = new DropBoxCloudFile(file, dbClient);
results.add(cf);
}
return results;
}
}
public class DropBoxCloudFile implements CloudFile {
private DropBoxClient dbClient;
private DbFile dbFile;
public DropBoxCloudFile(DbFile dbFile, dbClient) {
this.dbFile = dbFile;
this.dbClient = dbClient;
}
public String getId() {
return dbFile.getId();
}
public boolean hasUrl() {
return true;
}
public String getUrl() {
return dbFile.getFileUrl();
}
public String getName() {
return dbFile.getFileName();
}
public InputStream getInputStream() {
return dbClient.createStreamOfFile(dbFile);
}
public void write(OutputStream out) {
...
}
public void delete() {
dbClient.deleteFile(dbFile.getId());
}
}
- 파일 목록, 다운로드 기능 구현
public List<CloudFile> getFileInfos(CloudId cloudId) {
CloudFileSystem fileSystem = CloudFileSystemFactory.getFileSystem(cloudId);
return fileSystem.getFiles();
}
public void download (CloudFile file, File localTarget) {
file.write(new FileOutputStream(localTarget));
}
- BOX 클라우드 지원 추가
Concrete 클래스를 구현하면 box 클라우드 지원 가능
그리고 CloudFileSystemFactory에서 CloudFileId에 따라서 알맞게 box file 시스템을 리턴하도록 하면 됨
- 파일 목록, 다운로드 기능 구현 (BOX 지원 추가 이후)
public List<CloudFile> getFileInfos(CloudId cloudId) {
CloudFileSystem fileSystem = CloudFileSystemFactory.getFileSystem(cloudId);
return fileSystem.getFiles();
}
public void download(CloudFile file, File localTarget) {
file.write(new FileOutputStream(localTarget));
}
- 파일 복사 기능
public void copy(CloudFile file, CloudId target) {
CloudFileSystem fileSystem = CloudFileSystemFactory.getFileSystem(target);
fileSystem.copyFrom(file);
}
-- DropBoxFileSystem
private DropBoxClient dbClient = new DropBoxClient(...);
public void copyFrom(CloudFile file) {
if (file.hasUrl())
dbClient.copyFromUrl(file.getUrl());
else
dbClient.copyFromInputStream(file.getInputStream(), file.getName());
}
-- NcloudFileSystem
private NcloudClient nClient = new NCloudClient(...);
public void copyFrom(CloudFile file) {
File tempFile = File.createTemp();
file.write(new FileOutputStream(tempFile));
nClient.upload(tempFile, file.getName());
}
- 추상화 결과
그리고 이 코드는 특정 클라우드 관련 코드가 한 곳에 모인다는 장점도 있음
이것이 바로 OCP(Open-Closed Principle, 개방-폐쇄 원칙)
기능을 변경하거나 확장에는 열려 있으면서 그 기능을 사용하는 코드는 수정하지 않아야 한다.
Author And Source
이 문제에 관하여([객체 지향 프로그래밍 입문] 5. 추상화 예시), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@software/객체-지향-프로그래밍-입문-5.-추상화-예시저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)