{"meta":{"title":"횡단 관심사 처리","intro":"Copilot Chat 는 코드가 있는 메서드 또는 함수의 핵심 관심사가 아닌 우려 사항과 관련된 코드를 방지하는 데 도움이 될 수 있습니다.","product":"GitHub Copilot","breadcrumbs":[{"href":"/ko/copilot","title":"GitHub Copilot"},{"href":"/ko/copilot/tutorials","title":"자습서"},{"href":"/ko/copilot/tutorials/copilot-cookbook","title":"GitHub Copilot 활용 안내서"},{"href":"/ko/copilot/tutorials/copilot-cookbook/refactor-code","title":"코드 리팩터링"},{"href":"/ko/copilot/tutorials/copilot-cookbook/refactor-code/handle-cross-cutting","title":"전반적인 측면 처리"}],"documentType":"article"},"body":"# 횡단 관심사 처리\n\nCopilot Chat 는 코드가 있는 메서드 또는 함수의 핵심 관심사가 아닌 우려 사항과 관련된 코드를 방지하는 데 도움이 될 수 있습니다.\n\n횡단 관심사는 로깅, 보안, 데이터 유효성 검사, 오류 처리와 같은 시스템의 여러 부분에 영향을 주는 프로그램의 애스팩트입니다. 코드베이스 전체에 분산되어 코드 중복과 유지 관리 문제가 발생할 수 있습니다.\n\nCopilot Chat 는 AOP(Aspect-Oriented 프로그래밍) 사례의 구현을 제안하거나 데코레이터 및 미들웨어 패턴을 사용하여 이러한 문제를 모듈식으로 유지 관리 가능한 방식으로 중앙 집중화하여 교차 절단 문제를 리팩터링하는 데 도움이 될 수 있습니다.\n\n## 예제 시나리오\n\n로깅이 발생하는 여러 서비스 파일이 포함된 Python 프로젝트가 있다고 상상해 보세요. 기록되는 정보는 개별 서비스 파일 내에서 정의됩니다. 나중에 애플리케이션을 수정하거나 확장하면 이 디자인으로 인해 로그 항목의 콘텐츠와 스타일이 일치하지 않을 수 있습니다. 로깅 동작을 통합하고 중앙 집중화하여 프로젝트 전체에 분산되지 않도록 할 수 있습니다.\n\n다음은 예제 프로젝트의 세 가지 파일인 진입점 파일(`main.py`), 로그 메시지 구성 파일(`logging_config.py`) 및 서비스 파일(`order_service.py`) 중 하나입니다. 예제 서비스 파일은 애플리케이션의 특정 부분에 대한 비즈니스 논리와 함께 로그 정보가 정의되는 방법을 보여줍니다.\n\n### main.py\n\n```python\nimport logging\nfrom logging_config import setup_logging\nfrom payment_service import PaymentService\nfrom order_service import OrderService\nfrom shipping_service import ShippingService\nfrom inventory_service import InventoryService\nfrom notification_service import NotificationService\n\ndef main():\n    setup_logging()\n    payment_service = PaymentService()\n    order_service = OrderService()\n    shipping_service = ShippingService()\n    inventory_service = InventoryService()\n    notification_service = NotificationService()\n\n    # Example usage\n    payment_service.process_payment({\"amount\": 100, \"currency\": \"USD\"})\n    order_service.place_order({\"item\": \"Book\", \"quantity\": 1})\n    shipping_service.ship_order({\"item\": \"Book\", \"quantity\": 1})\n    inventory_service.update_inventory(\"Book\", -1)\n    notification_service.send_notification(\"Order has been placed and shipped.\")\n\nif __name__ == \"__main__\":\n    main()\n```\n\n### logging\\_config.py\n\n```python\nimport logging\n\ndef setup_logging():\n    logging.basicConfig(level=logging.INFO,\n                  format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')\n```\n\n### order\\_service.py\n\n```python\nimport logging\n\nclass OrderService:\n    def __init__(self):\n        self.logger = logging.getLogger(__name__)\n\n    def place_order(self, order):\n        self.logger.info(\"Entering place_order method.\")\n        try:\n            # In here would be the business logic for placing an order\n            # ...\n            self.logger.info(\"Order placed successfully.\")\n        except Exception as e:\n            self.logger.error(f\"Error in place_order method: {e}\")\n            raise\n        finally:\n            self.logger.info(\"Exiting place_order method.\")\n```\n\n## 예제 프롬프트\n\nVS Code 또는 Visual Studio에서 프로젝트 작업 영역을 열고 Copilot Chat 보기에서 다음 프롬프트를 입력합니다.\n\n```copilot copy\n@workspace Refactor this project by using AOP to avoid logging that has cross-cutting concerns\n```\n\n> \\[!NOTE]\n> `@workspace`VS Code의 채팅 참가자는 Visual Studio 작업 영역의 모든 코드에 대한 관련 정보를 Copilot에 제공합니다. 프로젝트의 구조와 코드의 여러 부분이 상호 작용하는 방식을 고려하고자 할 때 `@workspace`를 Copilot에 사용할 수 있습니다. JetBrains IDE를 사용하는 경우 `@project` 대신 `@workspace` 사용합니다.\n\n## 응답 예제\n\nCopilot 다음과 같이 응답합니다.\n\n> \\[!NOTE] 다음 응답이 예제입니다. Copilot Chat 응답은 비결정적이므로 여기에 표시된 응답과 다른 응답을 얻을 수 있습니다.\n\n> AOP(관점 지향 프로그래밍)를 사용하여 이 프로젝트를 리팩터링하여 횡단 관심사로 로깅을 처리하려면 `aspectlib`와 같은 라이브러리를 사용할 수 있습니다. 수행할 방법은 다음과 같습니다.\n>\n> 1.\n\n`aspectlib`를 설치하십시오:\n\n> `pip install aspectlib`\n>\n> 1.\n\n`logging_aspect.py`라는 새 파일에 로깅하기 위한 애스팩트를 만듭니다.\n\n> ```python\n> import aspectlib\n> import logging\n>\n> @aspectlib.Aspect(bind=True)\n> def log_method_call(cutpoint, *args, **kwargs):\n>     logger = logging.getLogger()\n>     method_name = cutpoint.__name__\n>     logger.info(f\"Entering method: {method_name}\")\n>     try:\n>         result = yield aspectlib.Proceed\n>         logger.info(f\"Method {method_name} executed successfully.\")\n>         return result\n>     except Exception as e:\n>         logger.error(f\"Error in method {method_name}: {e}\")\n>         raise\n>     finally:\n>         logger.info(f\"Exiting method: {method_name}\")\n> ```\n>\n> 1.\n\n`main.py`의 서비스 메서드에 해당 애스팩트를 적용합니다.\n\n> ```python\n> import logging\n> from logging_config import setup_logging\n> from payment_service import PaymentService\n> from order_service import OrderService\n> from shipping_service import ShippingService\n> from inventory_service import InventoryService\n> from notification_service import NotificationService\n> from logging_aspect import log_method_call\n> import aspectlib\n>\n> def main():\n>     setup_logging()\n>\n>     # Apply logging aspect to service methods\n>     aspectlib.weave(PaymentService.process_payment, log_method_call)\n>     aspectlib.weave(OrderService.place_order, log_method_call)\n>     aspectlib.weave(ShippingService.ship_order, log_method_call)\n>     aspectlib.weave(InventoryService.update_inventory, log_method_call)\n>     aspectlib.weave(NotificationService.send_notification, log_method_call)\n>\n>     payment_service = PaymentService()\n>     order_service = OrderService()\n>     shipping_service = ShippingService()\n>     inventory_service = InventoryService()\n>     notification_service = NotificationService()\n>\n>     # Example usage\n>     payment_service.process_payment({\"amount\": 100, \"currency\": \"USD\"})\n>     order_service.place_order({\"item\": \"Book\", \"quantity\": 1})\n>     shipping_service.ship_order({\"item\": \"Book\", \"quantity\": 1})\n>     inventory_service.update_inventory(\"Book\", -1)\n>     notification_service.send_notification(\"Order has been placed and shipped.\")\n>\n> if __name__ == \"__main__\":\n>     main()\n> ```\n\nCopilot 그런 다음 모든 서비스 클래스에서 로깅 코드를 제거하도록 지시하고 수정된 파일에 대한 코드를 제공합니다. 예를 들어 `order_service.py`의 수정된 버전은 다음과 같습니다.\n\n```python\nclass OrderService:\n    def place_order(self, order):\n        # In here would be the business logic for placing an order\n        # ...\n        pass\n```\n\n프로젝트의 리팩터링된 버전에서 동일한 로깅 작업이 수행되지만, 로깅 코드는 단일 파일에서 중앙 집중화됩니다.\n\n## 추가 읽기\n\n* [GitHub Copilot 채팅에 대한 프롬프트 엔지니어링](/ko/copilot/concepts/prompting/prompt-engineering)\n* [GitHub 부필로트 사용에 대한 모범 사례](/ko/copilot/get-started/best-practices)"}