add design patterns:
decorate
observer