수행 내용

  • 의존 모둠 안내 (질문 및 기술적 이슈 해결 기본 방침)
    • 예) 2A 모둠일 경우 2모둠 (2A, 2B) 안에서 해결 시도 → 해결 불가 시 3모둠 도움 요청 → 리뷰어 도움 요청 (한 노드 당 최대 3시간으로 기준 설정)
  • 타입의 일반화, 추상화, 은닉화, 캡슐화
  • 접근 제어 학습
  • 묵찌빠 프로젝트 2B 모둠 그라운드 룰 설정
  • 묵찌빠 프로젝트 Step 1 의사코드 설계 (w/ Steven)

학습 내용

활동 학습

코드 작성 시 유의 사항

  • 코드를 작성하기 전 어떤 단계를 거칠지 플로우 차트를 먼저 그려본다.
  • 예상 시간(계획 일정)과 실제 걸리는 시간을 스스로 측정하여 얼마나 괴리가 발생하는지 판단하고 숙지한다.

타입의 일반화, 추상화, 은닉화, 캡슐화

타입

세상의 물건들을 공통적인 특징으로 묶어놓은 설계도. 설계도를 통해 메모리에 실제로 만들어지는 것은 인스턴스라 한다.

일반화 (Generalization)

연관성 있는 두 개 이상의 개체 집합을 묶어 좀 더 상위의 개체 집합을 만드는 것

일반화의 예시

  • 인간: 눈, 코, 입이 있고 생각하고 판단할 수 있으며 이족보행을 한다.
  • 자동차: 네 개의 바퀴와, 엔진, 변속기, 브레이크, 공조장치 등과 같은 장치가 있는 기계
  • 옵셔널: 포장된 값이 있거나 없을 수 있는 것

일반화 방식, 프로퍼티와 메서드

  1. 특성값/상태값 (프로퍼티): 같은 휴대폰이라도 불량이냐
  2. 공통적으로 할 수 있는 행위 (메서드)

개체 일반화

특정 개체들의 공통점을 일반화하여 개체들이 할 수 있는 행위를 메서드로, 개체들이 갖는 특성을 프로퍼티로 정의한다.

추상화 (Abstraction)

중요한 특징을 추출해서 간단하게 표현하는 것 (예, 지하철 노선도, 타입을 만드는 행위)

  • 일반화한 내용을 추리는 것을 추상화라 한다.
  • 추상화는 구현 목적에 따라 특징의 취사 선택이 가능하므로 일반화의 후행 단계라 할 수 있다.

은닉화 (Hiding)

외부로 드러나지 않아야 할 정보를 숨기는 것.

캡슐화 (Encapsulation)

중요 사항을 감추고 외부에서 개체를 사용할 수 있는 수단을 제공하는 것. (예, 전원 버튼을 누른다 -> 컴퓨터가 켜진다). 캡슐화도 일부 은닉화의 과정을 거침. 사용자 (다른 프로그래머)가 사용할 내용은 메서드로 구현.

타입의 일반화, 추상화, 캡슐화, 은닉화 실습

세탁기 타입

  • 특성 (프로퍼티)
    색깔 / 제조일 / 일련번호 / 유형 ( 일반형, 드럼형 ) / 모터 종류 / 크기 / 세탁용량 / 가격 / 브랜드 / 불량 여부 / 건조기 일체 여부 / 에너지등급 / 인증(적합성평가인증, 안전확인인증) / 생활방수지원 여부 등
  • 하는 일 / 기능 (메서드)
    세탁 / 헹굼 / 탈수 / 물온도조절 / 물양 조절 / 삶음 / 예약 / 건조 / 배수 / 빨래 추가 / 물 양 체크 / 물 온도 체크 / 세탁물 중량 측정 등
// 세탁기 타입 구현 코드 (세부 메서드 구현하지 않음)
class LaundryMachine {
	let color: String
	let manufacturedDate: String
	let serialNumber: String
	let laundryMachineType: String
	let motorType: String
	let washingMachineSize: Int
	let washingCapacity: Int
	let brand: String
	let dryerStatus: Bool
	let certification: Bool
	private var powerState: Bool = false
	private var price: Int
	
	init(
		color: String,
		manufacturedDate: String,
		serialNumber: String,
		laundryMachineType: String,
		motorType: String,
		washingMachineSize: Int,
		washingCapacity: Int,
		brand: String,
		dryerSupported: Bool,
		certification: Bool,
		price: Int
	) {
		self.color = color
		self.manufacturedDate = manufacturedDate
		self.serialNumber = serialNumber
		self.laundryMachineType = laundryMachineType
		self.motorType = motorType
		self.washingMachineSize = washingMachineSize
		self.washingCapacity = washingCapacity
		self.brand = brand
		self.dryerSupported = dryerSupported
		self.certification = certification
		self.price = price
	}

	func operate() {
    		guard self.powerState == true else {
        	return
        	}
                let laundryWeight = checkLaundryWeight()
                if isExceededCapacity(laundryWeight : laundryWeight) {
                    return
                } 
                calculateLaundryTime(laundryWeight: laundryWeight)
                wash()
                rinse()
                dehydrate()
                ringEndAlarm()
	}
	
	func wash(motorType: String, laundryWeight) {
    	addWater()
        ...
        checkWaterTemperature()
        checkWaterAmount()
        ...
    	}
	func rinse(현재 세탁물 용량, 세탁기의 헹굼시간) {}
	func dehydrate(현재 무게) {}//탈수
	func reserveTime(예약 시간, 예약한 기능) {}
	func drainWater(현재 세탁물용량, 세탁기의 배수용량) {} //배수
	func isExceededCapacity() {}
	func addLaundry(최대세탁물 용량, 현재세탁물 용량, 추가할빨래) {}
	func checkLaundryWeight() {
    	return laundryWeight
    	}
        func turnPowerOnOrOff() {
            self.powerState.toggle()
        }
	func caculateLaundryTime(laundryWeight: laundryWeight) {}
	func checkWaterTemperature() {}
    	func ringEndAlarm() {}
	public func changePrice(price: Int) {
	self.price = price
   	}
}

let ryanLaundryMachine = LaundryMachine(
	color: "blue",
	manufacturedDate: "20000101",
	serialNumber: "A9217962",
	laundryMachineType: "tongdori",
	motorType: "DD-inverter",
	washingMachineSize: 50,
	washingCapacity: 25,
	brand: "무야호!",
	dryerSupported: false,
	certification: true,
	price: 2720000
)

ryanLaundryMachine.changePrice(price: 300000) // 그래도 예전엔 잘 나갔었는데.. 떨이합니다..
dump(ryanLaundryMachine)

접근제어 (Access Control)

코드끼리 상호작용을 할 때 파일 간 또는 모듈 간에 접근을 제한할 수 있는 기능이다. 은닉화를 구현하기 위한 핵심기능.

접근 수준 (Access Level)

접근 제어를 구현하는 방법이다. 각 타입 (클래스, 구조체, 열거형 등)과 타입 내부의 프로퍼티, 메서드, 이니셜라이저, 서브스크립트 각각에 특정 접근 수준을 지정 가능하다.

접근 수준의 분류

  • 개방 접근 수준 (open): 모듈 외부에서의 접근을 허용한다. 클래스와 클래스의 멤버만 사용 가능하다. 개방 접근 수준을 제외한 모든 접근 수준의 클래스는 클래스가 정의된 모듈 안에서만 상속, 재정의가 가능하며 개방 접근 수준 클래스의 경우 정의된 모듈 밖에서도 가능하다.
  • 공개 접근 수준 (public): 모듈 외부에서의 접근을 허용한다. 주로 프레임워크에서 외부와 연결될 인터페이스를 구현하는데 많이 쓰인다.
  • 내부 접근 수준 (internal): 모듈 내부에서의 접근을 허용한다. 기본적으로 모든 요소에 암묵적으로 지정하는 기본 접근 수준이다. 소스파일이 속해 있는 모듈 어디에서든 쓰일 수 있지만 모듈을 가져다 쓰는 외부 모듈에서는 접근할 수 없다.
  • 파일 외부 비공개 접근 수준 (fileprivate): 파일 내부의 접근을 허용한다. 구현된 소스파일 내부에서만 사용할 수 있다. 해당 소스파일 외부에서 값이 변경되거나 함수를 호출하면 부작용이 생길 수 있는 경우에 사용한다.
  • 비공개 접근 수준 (private): 기능이 정의된 내부에서의 접근만을 허용한다. 같은 소스파일 안에 구현한 다른 타입이나 기능에서도 사용할 수 없다.

읽기 전용 구현

접근 제어를 통해 저장 프로퍼티의 값을 가져갈 수 있어도 변경할 수 없도록 구현하는 방법이다. 접근수준(set)과 같은 문법으로 사용한다.

public struct Team6 {
    ...
    // 공개 접근수준 저장 프로퍼티 scrumTime, 설정자는 비공개 접근 수준
    public private(set) var scrumTime: String = "Everyday 09:30 AM"
    ...
}

문제점 / 고민한 점

실습 대상의 타입 선정

세탁기 타입의 타입 선정에서 구조체와 클래스를 고민하였다.

은닉화 방법

저장 프로퍼티인 price 등을 외부에서 설정할 수 없도록 만드는 방법을 고민하였다.

해결 방법

  • 세탁기 타입은 향후 기능 추가/변경/삭제, 프로퍼티 추가/변경 등의 사유로 상속하여 사용할 여지가 있으므로
    클래스 타입을 선정하였다.
  • 외부에서 접근하여 세탁기 타입의 중요한 저장 프로퍼티(price)를 설정할 수 없도록 읽기 전용으로 구현하였으며, changePrice(price:) 메서드로만 프로퍼티를 변경할 수 있도록 은닉화하였다.
profile
합리적인 해법 찾기를 좋아합니다.

0개의 댓글