IT 인프라
엔터프라이즈 IT 환경을 운영하고 관리하는 데 필요한 구성 요소
IT 서비스 및 솔루션을 제공하기 위해 필요한 IT 환경(서비스 및 플랫폼)을 구축, 개발, 운영하기 위해 필요한 모든 구성요소
플랫폼 - 하드웨어, 네트워킹요소, 데이터 스토리지
서비스 - 운영체제, 소프트웨어
IT 인프라 구성 방식
집약형 - 한대의 시스템으로 모든 기능을 해결
분산형 - 여러대의 시스템을 조합해서 하나의 시스템으로 구축
분산형 아키텍처
서버별로 다른 역할을 하도록 시스템을 수직으로 확장하는 구조 - c/s, 3-tier
수평 분할형 아키텍처
용도가 같은 서버를 늘려나가는 방식 - sharding, Partitioning
스탠바이형 아키텍처
물리 서버를 최소 두 대를 준비하여 한 대가 고장 나면 가동 중인 소프트웨어를 다른 한 대로 옮겨서 운영하는 방식
스탠바이, HA(High Availiability), Active-Standby 라고도 함
client-server : 화면 표시나 단순한 계산은 클라이언트에서 실행하고, 필요한 경우(데이터 요청 등) 서버에서 데이터 요청
3-tier 아키텍처
응용프로그램을 3개의 논리적 및 물리적 컴퓨팅 계층으로 구성하는 소프트웨어 아키텍처
프리젠테이션 계층 또는 사용자 인터페이스, 데이터를 처리하는 애플리케이션 계층,
그리고 애플리케이션과 연관된 데이터를 저장 및 관리하는 데이터 계층으로 구성
보다 신속한 개발, 확장성 개선, 안정성 향상, 보안성 강화
프레젠테이션 계층 (Presentation Tier)
일반 사용자가 애플리케이션과 상호작용하는 애플리케이션의 사용자 인터페이스 및 통신 계층
주요 목적은 정보를 표시하고 사용자로부터 정보를 수집하는 것
애플리케이션 계층
프리젠테이션 계층에서 수집된 정보를 다양한 비즈니스 규칙(로직)을 이용해서 처리함
프레젠테이션 계층에서 온 요청을 받아, 요구에 필요한 데이터를 데이터 계층에 요청하며
전달 받은 데이터를 특정 처리 및 가공을 하여 프레젠테이션 계층에 전달하는 것을 담당
데이터 계층
어플리케이션 계층의 요청에 따라 데이터 입출력 처리
데이터베이스와 데이터베이스에 접근하여 데이터를 읽거나 쓰는 것을 관리하는 계층
소프트웨어의 좋은 설계
유지보수가 용이해야 함
높은 응집도와 낮은 결합도를 가지도록 요소(모듈)를 적절히 배치하는 것 - 소프트웨어 설계 품질을 판단하는 기준
모듈: 크기와 상관없이 클래스나 패키지, 라이브러리와 같이 프로그램을 구성하는 임의의 요소를 의미
결합도Coupling: 다른 모듈과의 상호 의존성 정도, 모듈 간의 의존이 심하면 모듈의 독립성이 악화
모듈을 수정하려고 하는데, 다른 모듈이 영향을 받으면 수정하기 힘들 테니,
그 영향이 거의 없을수록 부담없이 수정이 가능
응집도Cohesion: 모듈에 포함된 내부 요소들이 하나의 책임/목적을 수행하기 위해 얼마나 잘 연관되었나의 정도
응집도가 높으면 수정해야 될 코드가 한 군데에 모여있기 때문에
하나(최소한)의 모듈만 분석해서 수정하면 되니 유지보수 하기 좋음
파이썬 객체지향 프로그래밍
OOP : object oriented programming
프로그램을 명령어들의 단순 묶음이라고 보는 시각에서
벗어나 독립된 객체들의 모음이라고 보는 시각에 근거해서
프로그래밍하는 패러다임
프로그램을 보다 유연하게 작성할 수 있고
프로그램 코드의 재사용을 높일수 있으며
대규모 소프트웨어 개발시 유지보수가 용이해짐
프로그램의 각 구성요소를 실제세계의 객체와 유사하게
디자인해서 클래스로 정의하는 것에 중점을 둠
# ex) 성적처리 프로그램
# 이름,국어,영어,수학을 입력하면
# 총점,평균,학점을 출력
# 성적 입력
name = input('이름은 ?')
kor = int(input('국어는 ?'))
eng = int(input('영어는 ?'))
mat = int(input('수학은 ?'))
# 성적 처리
tot = kor + eng + mat
avg = tot / 3
grd = '가'
if (avg >= 90): grd = '수'
elif (avg >= 80): grd = '우'
elif (avg >= 70): grd = '미'
elif (avg >= 60): grd = '양'
# 결과 출력
print('입력:%s %s %s %s' % (name, kor,eng,mat))
print('결과:%s %.1f %s' % (tot, avg, grd))
# ex) 성적처리 프로그램 II
# 함수 기반 프로그래밍 : 처리코드들을 하나의 이름으로 묶음
def readSungJuk():
name = input('이름은 ?')
kor = int(input('국어는 ?'))
eng = int(input('영어는 ?'))
mat = int(input('수학은 ?'))
return name,kor,eng,mat
def computeSungJuk(kor,eng,mat):
tot = kor + eng + mat
avg = tot / 3
grd = '가'
if (avg >= 90): grd = '수'
elif (avg >= 80): grd = '우'
elif (avg >= 70): grd = '미'
elif (avg >= 60): grd = '양'
return tot,avg,grd
def printSungJuk(name,kor,eng,mat,tot,avg,grd):
print('입력:%s %s %s %s' % (name,kor,eng,mat))
print('결과:%s %.1f %s' % (tot,avg,grd))
# 프로그램 실행
name,kor,eng,mat = readSungJuk()
tot,avg,grd = computeSungJuk(kor,eng,mat)
printSungJuk(name,kor,eng,mat,tot,avg,grd)
# ex) 성적처리 프로그램 3
# 객체지향 프로그램 : 함수들과 관련된 변수들을 하나로 묶음
# 성적데이터를 담고있는 클래스와
# 성적처리에 필요한 기능들로만 구성된 클래스로 나눠 작성
# OOP에서의 클래스 특성
# 1. 값만 저장하는 클래스 : VO, DTO
# 2. 기능만 저장하는 클래스 : DAO, BO
# 데이터베이스 연동 클래스 : CRUD 기능 지원
# 3. UI처리만 저장하는 클래스 : UO
# OOP 3대 특성
# 캡슐화
# 상속
# 다형성
# OOP 5대 원칙
# 결합도, 응집도
# SOLID
# VO 클래스 만드는 법
# 생성자 : __init__
# private 멤버 변수 선언
# setter/getter : @setter, @property (@:데코레이터)
# 클래스 정의
# 클래스 이름은 camel 표기법으로 지음
# class 클래스명(상속여부):
# 생성자
# setter/getter
# 메서드
class SungJukVO(): # 성적 데이터와 관련된 변수만 선언
# 생성자 : 클래스 객체 생성시 초기화 작업 진행하는 함수
# 생성자를 멤버변수 선언 및 기본값을 지정할 수 있음
def __init__(self):
# 멤버변수에 접근제한 기능 부여
# 멤버명에 __를 추가하면 private 접근 제한 부여 메서드를통해서만 가능하게
self.__name = '혜교'
self.__kor = 0
self.__eng = 0
self.__mat = 0
self.__tot = 0
self.__avg = 0.0
self.__grd = '가'
# setter/getter
# @property를 먼저 정의하고, @setter를 정의해야 함
# @property
# def 멤버 변수명(self)
# return self.멤버변수명
# 멤버 변수명.@setter
# def 멤버변수명(self, 멤버변수명):
# self.멤버변수명 = 멤버변수명
@property # 멤버 변수값을 외부로 반환
def name(self):
return self.__name
@name.setter # 외부에서 전달해준 값을 멤버변수에 대입
def name(self, name):
self.__name = name
@property
def kor(self):
return self.__kor
@kor.setter
def kor(self, kor):
self.__kor = kor
@property
def eng(self):
return self.__eng
@eng.setter
def eng(self, eng):
self.__eng = eng
@property
def mat(self):
return self.__mat
@mat.setter
def mat(self, mat):
self.__mat = mat
@property
def tot(self):
return self.__tot
@tot.setter
def tot(self, tot):
self.__tot = tot
@property
def avg(self):
return self.__avg
@avg.setter
def avg(self, avg):
self.__avg = avg
@property
def grd(self):
return self.__grd
@grd.setter
def grd(self, grd):
self.__grd = grd
# 클래스에 대한 변수(객체) 선언
# 변수명 = 클래스 생성자()
sj = SungJukVO() #클래스만 만들면 따로따로 선언할 필요 없음 객체를 만드는 틀
# 객체의 멤버 변수에 접근 : 객체명.멤버변수명
# 멤버변수를 private으로 선언하면 은닉변수가 되어 접근불가 - 캡슐화
# 이럴 경우 setter/getter 으로 정의된 함수(메서드method)로만 접근가능
print(sj.name, sj.kor, sj.eng, sj.mat) #바로 접근 불가에러
# 이름 : EmployeeVO
# 변수명 : empid, fname, lname, email,
# phone, hdate, jobid, sal, comm,
# mgrid, deptid
class EmployeeVO():
def __init__(self):
self.__empid = 000
self.__fname = ''
self.__lname = ''
self.__email = ''
self.__phone = ''
self.__hdate = ''
self.__jobid = ''
self.__sal = 0
self.__comm = 0.0
self.__mgrid = 0
self.__deptid = 0
@property
def empid(self):
return self.__empid
@empid.setter
def empid(self, empid):
self.__empid = empid
@property
def fname(self):
return self.__fname
@fname.setter
def fname(self, fname):
self.__fname = fname
@property
def lname(self):
return self.__lname
@lname.setter
def lname(self, lname):
self.__lname = lname
@property
def email(self):
return self.__email
@email.setter
def email(self, email):
self.__email = email
@property
def phone(self):
return self.__phone
@phone.setter
def phone(self, phone):
self.__phone = phone
@property
def hdate(self):
return self.__hdate
@hdate.setter
def hdate(self, hdate):
self.__hdate = hdate
@property
def jobid(self):
return self.__jobid
@jobid.setter
def jobid(self, jobid):
self.__jobid = jobid
@property
def sal(self):
return self.__sal
@sal.setter
def sal(self, sal):
self.__sal = sal
@property
def comm(self):
return self.__comm
@comm.setter
def comm(self, comm):
self.__comm = comm
@property
def mgrid(self):
return self.__mgrid
@mgrid.setter
def mgrid(self, mgrid):
self.__mgrid = mgrid
@property
def deptid(self):
return self.__deptid
@deptid.setter
def deptid(self, deptid):
self.__deptid = deptid
emp = EmployeeVO()
print(emp.empid, emp.fname, emp.lname, emp.email,
emp.phone, emp.hdate, emp.jobid, emp.sal, emp.comm,
emp.mgrid, emp.deptid)
steve = EmployeeVO()
print(steve.fname, steve.lname)
steve.fname = 'steve'
# setter에 의해 값이 멤버변수에 대입
steve.lname= 'king'
print(steve.fname, steve.lname)
# ex) 성적처리 프로그램 3
# 객체지향 프로그램 : 함수들과 관련된 변수들을 하나로 묶음
# 성적데이터를 담고있는 클래스와
# 성적처리에 필요한 기능들로만 구성된 클래스로 나눠 작성
# OOP에서의 클래스 특성
# 1. 값만 저장하는 클래스 : VO, DTO
# 2. 기능만 저장하는 클래스 : DAO, BO
class SungJukVO():
# 객체 생성시 초기화할 멤버변수에 대한 매개변수 선언
def __init__(self, name, kor, eng, mat):
self.name = name
self.kor = kor
self.eng = eng
self.mat = mat
self.__tot = 0
self.__avg = 0.0
self.__grd = '가'
# 응집도 관점에서 볼때 성적처리 코드가
# getter 별로 흩어져 있음
# -> 독립적인 메서드로 작성할것 추천!
@property
def __tot(self):
self.__tot = self.kor + self.eng + self.mat
return self.__tot
@property
def __avg(self):
self.__avg = self.__tot / 3
return self.__avg
@property
def __grd(self):
if self.__avg >= 90 : self.__grd ='수'
elif self.__avg >= 80 : self.__grd ='우'
elif self.__avg >= 70 : self.__grd ='미'
elif self.__avg >= 60 : self.__grd ='양'
return self.__grd
# 성적 객체 생성
suji = SungJukVO('수지', 98, 78, 67)
print(suji.name, suji.kor, suji.eng, suji.mat)
suji.name = '지수' # 특정 속성의 값을 변경 (신뢰성에 영향안줌)
# 수지성적처리 : 클래스 외부에서 수행
suji.tot = suji.kor + suji.eng + suji.mat
print(suji.tot)
# 정상적이지 않은 방식으로 총점을 대입 -> 신뢰성 저하
suji.tot = 299 # 비추! -> tot를 private하게 선언 tot는 세개의 점수의 합이기때문에
# 클래스 내부에 선언된 getter를 이용해 성적결과 알아보기
print(suji.tot, suji.avg, suji.grd)
# 개선된 성적 클래스
class SungJukVO():
# self : 클래스의 멤버변수임을 나타내기 위한 지시자
# 매개변수 shadowing을 방지하기 위해 사용
# 또한 메서드의 첫 매개변수는 self로 선언해야함
def __init__(self, name, kor, eng, mat):
self.name = name
self.kor = kor
self.eng = eng
self.mat = mat
self.__tot = 0
self.__avg = 0.0
self.__grd = '가'
# __str__ 멤버변수들의 값을 문자열화 해서
# 객체의 정보를 외부에 표현할 때 사용
def __str__(self):
self.computeSungjuk()
result = f'{self.name}\n{self.kor},' \
f'{self.eng},{self.mat}\n' \
f'{self.__tot},{self.__avg},{self.__grd}'
return result
# 성적처리
# 메서드도 private 프라이빗 선언하려면 : __메서드명
def computeSungjuk(self):
self.__tot = self.kor + self.eng + self.mat
self.__avg = self.__tot / 3
if self.__avg >= 90 : self.__grd ='수'
elif self.__avg >= 80 : self.__grd ='우'
elif self.__avg >= 70 : self.__grd ='미'
elif self.__avg >= 60 : self.__grd ='양'
jihyun = SungJukVO('지현', 98, 78, 67)
# 클래스에 정의된 __str__를 호출해서 객체 정보 출력
print(jihyun)
# 성적데이터를 담고있는 클래스(SungJukVO)와
# 성적처리에 필요한 기능들로만 구성된 클래스(SungJukService)로 나눠 작성
class SungJukVO():
def __init__(self, name, kor, eng, mat):
self.name = name
self.kor = kor
self.eng = eng
self.mat = mat
self.__tot = 0
self.__avg = 0.0
self.__grd = '가'
def __str__(self):
result = f'{self.name},{self.kor},' \
f'{self.eng},{self.mat},' \
f'{self.__tot},{self.__avg},{self.__grd}'
return result
# private 으로 선언된 tot, avg, grd에 대한 setter 정의
@property
def tot(self):
return self.__tot
@tot.setter
def tot(self, tot):
self.__tot = tot
@property
def avg(self):
return self.__avg
@avg.setter
def avg(self, avg):
self.__avg = avg
@property
def grd(self):
return self.__grd
@grd.setter
def grd(self, grd):
self.__grd = grd
class SungJukService():
# 성적데이터 입력 SungJukVO 객체생성
def readSungJuk(self):
name = input('이름은 ?')
kor = int(input('국어는 ?'))
eng = int(input('영어는 ?'))
mat = int(input('수학은 ?'))
return SungJukVO(name, kor, eng, mat)
# SungJukVO 형식의 변수 sj를 이용해서
# 총점, 평균, 학점 계산
def computeSungjuk(self, sj):
sj.tot = sj.kor + sj.eng + sj.mat
sj.avg = sj.tot / 3
if sj.avg >= 90 : sj.grd ='수'
elif sj.avg >= 80 : sj.grd ='우'
elif sj.avg >= 70 : sj.grd ='미'
elif sj.avg >= 60 : sj.grd ='양'
# compute 출력
# 테스트
sjsrv = SungJukService()
sjvo = sjsrv.readSungJuk()
sjsrv.computeSungjuk(sjvo)
print(sjvo)
# vo : value object
# 회원가입을 처리하는 클래스 생성
# MemberVO :
# userid, passwd, name, email, milege, grade
# MemberService :
# registerMember : 회원정보 입력
# processMemberGrade : 마일리지에 따라 회원등급 결정
# vip : 마일리지 - 10000이상
# gold : 마일리지 - 7000이상
# silver : 마일리지 - 4000이상
# bronze : 마일리지 - 2000이상
# member : 그외
class MemberVO():
def __init__(self, userid, passwd, name, email, milege):
self.userid = userid
self.passwd = passwd
self.name = name
self.email = email
self.milege = milege
self.grade = 'member'
def __str__(self):
result = f'{self.userid}{self.passwd}{self.name}{self.email}{self.milege}{self.grade}'
return result
class MemberService():
# 성적데이터 입력 SungJukVO 객체생성
def registerMember(self):
userid = input('아이디은 ?')
passwd = input('비번은 ?')
name = input('이름은 ?')
email = input('이메일은 ?')
milege = int(input('마일리지는 ?'))
return MemberVO(userid, passwd, name, email, milege)
def processMembergrade(self, mbvo):
if mbvo.milege >= 10000 : mbvo.grade = 'vip'
elif mbvo.milege >= 7000 : mbvo.grade = 'gold'
elif mbvo.milege >= 4000 : mbvo.grade = 'silver'
elif mbvo.milege >= 1000 : mbvo.grade = 'bronze'
mbsrv = MemberService()
mbvo = mbsrv.registerMember()
mbsrv.processMembergrade(mbvo)
print(mbvo)
# setter 접근 제한하기
import inspect
# inspect 모듈 이용
# 특정 setter의 호출이 정상적인지 확인
class SungJukVO():
def __init__(self, name, kor, eng, mat):
self.name = name
self.kor = kor
self.eng = eng
self.mat = mat
self.__tot = 0
self.__avg = 0.0
self.__grd = '가'
def __str__(self):
result = f'{self.name} {self.kor} ' \
f'{self.eng} {self.mat} ' \
f'{self.__tot} {self.__avg} {self.__grd}'
return result
# private으로 선언된 tot,avg,grd에 대한 setter 정의
@property
def tot(self): return self.__tot
@tot.setter
def tot(self, tot):
hasattr = self.__check_caller(inspect.stack()[1])
if hasattr: self.__tot = tot
else: raise AttributeError("Can't set value!!!")
@property
def avg(self): return self.__avg
@avg.setter
def avg(self, avg):
hasattr = self.__check_caller(inspect.stack()[1])
if hasattr: self.__avg = avg
else: raise AttributeError("Can't set value!!!")
@property
def grd(self): return self.__grd
@grd.setter
def grd(self, grd):
hasattr = self.__check_caller(inspect.stack()[1])
if hasattr: self.__grd = grd
else: raise AttributeError("Can't set value!!!")
def __check_caller(self, caller):
callattr = False
fnattr = caller.function
if hasattr(SungJukService, fnattr):
callattr = True
return callattr
'Python' 카테고리의 다른 글
PyCharm - 3 tier 아키텍처를 적용(VO, Service, DAO) (0) | 2022.05.25 |
---|---|
PyCharm - 상속, 추상 클래스 (0) | 2022.05.23 |
PyCharm - Dao (Data access object) (0) | 2022.05.22 |
PyCharm - 데이터베이스 (Oracle) (0) | 2022.05.20 |
PyCharm - 데이터베이스 (sqlite3) (0) | 2022.05.18 |