캡슐화와 추상화

Hyeseong·2022년 11월 28일
0

TIL

목록 보기
12/13

캡슐화

  • 온라인 상점에 들어온 새로운 고객을 맞이하는 코드를 작성
  • 인사말로 고객 환영.
  • 고객 혜택 제공
  • 세 개의 메서드를 가진 Greeter라는 단일 클래스를 포함한 greeter 모듈 작성
1 __init__(self, name) : Greeter 인스턴스에 저장할 name이라는 인자를 받음. 
                         이 이름은 인사말 메시지를 출력할 때 사용. 

2 _day(self) : 현재 요일(예, SUNDAY)을 반환
                         
3 _part_of_day(self) : 현재 시각이 오후 12시 이전이면 'morning'을 반환, 현재 시각이 오후 12시부터 오후 17시 전이면 'afternoon' 이후면 'evening'을 반환

4 greet(self, store) : 상점 이름이 store에 주어지면 앞의 두 가지 메서드 결과와 합께 다음과 같은 형태의 메시지를 출력
                       예. 
                        Hi, my name is <name>, and welcome to <store>!
                        How's your <day> <part of day> going?
                        Here's a coupon for 20% off!                                                                         

Greeter클래스가 노출해야 할 것은 greet method뿐이므로 밑줄이 앞에 붙은 메서드는 지역 메서드로 간주 할 수 있음.
이는 Greeter Class의 내부를 캡슐화하므로 외부에서의 관심사는 오직 인사말 뿐이다.

코드

# greeting module at online shopping website
from datetime import datetime

class Greeter:
    def __init__(self, name:str) -> None:
        self.name = name

    def _day(self):
        return datetime.now().strftime("%A")

    def _part_of_day(self):
        current_hour = datetime.now().hour
        if current_hour < 12:
            part_of_day = "morning"
        elif 12<= current_hour < 17:
            part_of_day = 'afternoon'
        else:
            part_of_day = 'evening'
        return part_of_day
    def greet(self, store):
        data = f"""
        Hi, my name is {self.name}, and welcome to {store}!
        How's your {self._day()} {self._part_of_day()} going?
        Here's a coupon for 20% off!    
        """
        print(data)
g = Greeter('hyeseong')
g.greet('ABC')
   Hi, my name is hyeseong, and welcome to ABC!
        How's your Monday afternoon going?
        Here's a coupon for 20% off!    

리팩토링

  • 요일, 시간정보를 가져오는 메서드를 클래스 밖으로 옮기고 모듈 내의 독립형 함수가 되게 하기

코드


def day():
    return datetime.now().strftime("%A")

def part_of_day():
    current_hour = datetime.now().hour
    if current_hour < 12:
        part_of_day = "morning"
    elif 12<= current_hour < 17:
        part_of_day = 'afternoon'
    else:
        part_of_day = 'evening'
    return part_of_day

from datetime import datetime

class Greeter:
    def __init__(self, name:str) -> None:
        self.name = name

    def greet(self, store):
        data = f"""
        Hi, my name is {self.name}, and welcome to {store}!
        How's your {day()} {part_of_day()} going?
        Here's a coupon for 20% off!    
        """
        print(data)
        
g = Greeter('hyeseong')
g.greet('ABC')
      Hi, my name is hyeseong, and welcome to ABC!
        How's your Monday afternoon going?
        Here's a coupon for 20% off!    
  • Greeter는 다른 세부 사항을 신경 쓰지 않고 오직 인사말을 만드는데 필요한 것만 알게됨.
  • 다른 클래스와 모듈에서도 퍼블릭하게 접근하여 함수를 사용할 수 있게 되는 장점
  • 클래스가 가진 목적에만 부합한 로직 작성이 가능

TIP

functools.partial :

  • 이미 인자가 고정된 기존 함수로 새로운 함수를 만들 수 있게 해줌.
  • 일반적으로 사용되는 함수가 더 구체적으로 명명된 함수처럼 동작해야 할 때.
from functools import partial 

def pow(x, power=1):
    return x ** power 

square = partial(pow, power=2)
cube = partial(pow, power=3)

print(square(2), cube(2))

믹스인

  • 깊은 상속 구조를 피할 수 있음
  • 덕 타이핑과 다중 상속
  • 많은 정적 타입 언어는 클래스가 다른 하나의 클래스만 상속하도록 하지만 파이썬은 임의의 수의 클래스로부터 상속 할 수 있게함 -> 믹스인
  • 예. 말도하고 구를수 있는 개를 만들기. 추후 이런 말하기, 구르기 기능을 할 수 있는 다른 동물을 만들려고 할 때 유용
  • 접미사로 Mixin을 사용
class SpeakingMixin:
    def speak(self):
        name = self.__class__.__name__.lower()
        print(f"The {name} says, Hello world")

class RolloverMixin:
    def roll_over(self):
        print('rolling~ rolling~')

class Dog(SpeakingMixin, RolloverMixin):
    pass 

d = Dog()
d.speak()
d.roll_over()
The dog says, Hello world
rolling~ rolling~

요약

  • 추상화는 코드에 대한 필수적인 이해를 나중으로 미루는 도구
  • 추상화는 다양한 형태(분해, 캡슐화, 프로그래밍 스타일, 상속과 구성)을 취함
  • 추상화에 대한 접근법들은 유용하지만 추상화의 내용과 사용 범위라는 중요한 고려 사항이 있음
  • 리팩토링은 반복작업이다. 한 번 했던 추상화 작업을 나중에 다시 해야 할 수 있음.
profile
어제보다 오늘 그리고 오늘 보다 내일...

0개의 댓글