{"meta":{"title":"Обработка перекрестных проблем","intro":"Копилот Чат может помочь вам избежать кода, который связан с задачей, отличной от основной задачи метода или функции, в которой находится код.","product":"GitHub Copilot","breadcrumbs":[{"href":"/ru/copilot","title":"GitHub Copilot"},{"href":"/ru/copilot/tutorials","title":"Учебники"},{"href":"/ru/copilot/tutorials/copilot-cookbook","title":"Кулинарная книга GitHub Copilot"},{"href":"/ru/copilot/tutorials/copilot-cookbook/refactor-code","title":"Код рефакторинга"},{"href":"/ru/copilot/tutorials/copilot-cookbook/refactor-code/handle-cross-cutting","title":"Обработка перекрестной обработки"}],"documentType":"article"},"body":"# Обработка перекрестных проблем\n\nКопилот Чат может помочь вам избежать кода, который связан с задачей, отличной от основной задачи метода или функции, в которой находится код.\n\nПерекрестные проблемы — это аспекты программы, влияющие на несколько частей системы, таких как ведение журнала, безопасность, проверка данных и обработка ошибок. Они могут быть разбросаны по базе кода, что приводит к дублированию кода и проблемам обслуживания.\n\nКопилот Чат может помочь реорганизовать перекрёстные вопросы, предлагая внедрение практик Aspect-Oriented программирования (AOP) или используя декораторов и шаблоны промежуточного программного обеспечения для централизации этих вопросов модульно, поддерживаемым образом.\n\n## Пример сценария\n\nПредставьте, что у вас есть Python-project, содержащий несколько сервисных файлов, в которых происходит логирование. Сведения, которые регистрируются, определяются в каждом из отдельных файлов службы. Если приложение изменено или расширено в будущем, это может привести к несоответствию содержимого и стиля записей журнала. Вы можете консолидировать и централизовать ведение логирования, чтобы избежать распространения этого по вашему project.\n\nВот три файла из нашего примера project: файл входной точки (`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\nОткройте VS Code рабочее пространство проекта в Visual Studio или Копилот Чат и введите следующую подсказку в представлении.\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 StudioCopilot контекст обо всём коде в вашем рабочем пространстве. Вы можете использовать `@workspace` , когда хотите Copilot рассмотреть структуру вашего проекта и то, как разные части вашего кода взаимодействуют. Если вы используете IDE JetBrains, используйте `@project` вместо `@workspace`.\n\n## Пример ответа\n\nCopilot отвечает следующим способом.\n\n> \\[!NOTE] Следующий ответ является примером. Ответы Копилот Чат являются недетерминированными, поэтому вы можете получить другой ответ, показанный здесь.\n\n> Для рефакторинга project использования Aspect-Oriented программирования (AOP) для ведения логирования как перекрёстной задачи, можно использовать библиотеку вроде `aspectlib`. Вот как это сделать:\n>\n> 1. Установите `aspectlib`:\n>\n>    `pip install aspectlib`\n>\n> 2. Создайте аспект для ведения журнала в новом файле:`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> 3. Применение аспекта к методам службы в `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В рефакторинговой версии project выполняются те же операции ведения журнала, но код логирования централизован в одном файле.\n\n## Дополнительные материалы\n\n* [Инженерия подсказок для GitHub Copilot Chat](/ru/copilot/using-github-copilot/prompt-engineering-for-github-copilot)\n* [Лучшие практики использования GitHub Copilot](/ru/copilot/using-github-copilot/best-practices-for-using-github-copilot)"}