언제 Magento 2에서 리포지토리와 팩토리를 사용해야합니까?


75

나는 Magento 2에서 몇 가지 튜토리얼을 봤는데, 약간 혼란 스럽습니다. 비즈니스 엔터티를 읽고 쓸 수있는 두 가지 방법이 기본적으로 있습니다.

데이터 검색

팩토리 접근법 사용

$object = $this->myFactory->create();
$object->load($myId);

리포지토리 접근 방식 사용

$repo   = $this->myRepository();
$object = $repo->getById($myId);

데이터를 저장

팩토리 접근법 사용

$object = $this->myFactory->create();
$object->load($myId);
$object->setData('something', 'somethingDifferent')->save();

리포지토리 접근 방식 사용

$repo   = $this->myRepository();
$object = $repo->getById($myId);
$object->setData('something', 'somethingDifferent');
$repo->save($object);

또한 의존성 주입을 사용하여 저장소와 팩토리 클래스를 모두 주입 할 수 있음을 알 수 있습니다. 이것은 적어도 나를 혼란스럽게합니다.

저장소 접근 방식과 팩토리 접근 방식은 언제 사용해야합니까? 우리가 따라야 할 가장 좋은 방법은 무엇입니까?


Factory, CollectionFactory 및 Repository를 사용하는 좋은 예는 \ Magento \ Setup \ Fixtures \ CategoryResolver에서 볼 수 있습니다.
Ricardo Martins

답변:


72

저장소가 있고 필요한 작업을 수행하는 경우 항상 저장소를 선호하십시오.

리포지토리는 서비스 계약의 일부로 인터페이스가 구현 Api되어 다른 모듈에 대한 공용 인터페이스로 사용됩니다.

전체로드에 저장소 사용

$model->load()서비스 계약의 일부가 아닙니다. 특정 주제에 대한 질문 이 있는데 , 답변이 유용 할 것입니다. 서비스 계약보다 $ model-> load ()를 선호하는 이유가 있습니까?

팩토리를 사용하여 새 엔티티 작성

리포지토리에는 새 엔터티를 만드는 방법이 제공되지 않으므로이 경우 팩토리가 필요합니다. 그러나 대한 팩토리를 사용해 인터페이스 등, Magento\Catalog\Api\Data\ProductInterfaceFactory- 그것은 DI 구성에 따라 올바른 구현을 작성합니다.

그런 다음 repository->save()방법을 사용하여 저장하십시오.

더 많은 관리가 필요한 경우 수집 공장 사용

다음은 공식 Magento 모범 사례는 아니지만 현재 리포지토리에서로드 할 항목을 세부적으로 제어 할 수는 없습니다. 검색 기준 API를 사용하면 필터를 정의 할 수 있지만 특정 EAV 속성을 선택하거나 조인 할 인덱스 테이블을 지정할 수있는 방법이 없습니다.

이는 서비스 계약 API에서 숨겨진 구현 세부 사항이지만 종종 이러한 구현 세부 사항이 중요하며이를 무시하면 성능이 저하됩니다. 이런 이유로 저장소가 나를 제한하자마자 더 이상 기본 컬렉션을 사용하는 것을 망설이지 않습니다.


2
팩토리를 사용하여 새 엔티티를 작성 하는 방법에 대한 코드 예제를 제공 할 수 있습니까? 설명에 일부 세부 사항이 누락되어 이해하기 어렵습니다. 대단히 감사합니다.
Key Shang


감사. 그러나 use the factory for the interface, such as Magento\Catalog\Api\Data\ProductInterfaceFactory - it will create the right implementation based on DI configuration.내가 이해할 수없는 요점입니다. 개발자 가이드는 InterfaceFactory를 소개하지 않습니다. repository->save()메서드를 사용 하여 새 엔티티를 저장 하는 방법은 무엇입니까? 리포지토리가 아닌 새 엔터티를 저장하기 위해 팩토리 만 사용할 수 있습니다.
Key Shang

@Key Shang, 인터페이스는 테이블의 모든 열을 저장하는 모든 설정 데이터 기능을 제공하므로 가능한 한 새로운 레코드를 저장할 수있는 인터페이스를 사용하십시오. InterfaceFactory 클래스는 di : compile의 일부로 생성되므로 var / generation 폴더에서 볼 수 있습니다.
stevensagaar

감사합니다. 이제 이해할 수 있습니다.
Key Shang

21

좋은 질문.

리포지토리와 팩토리 모두 엔터티에 액세스 할 수 있다고해도 나는 그들의 책임에 집중해야한다고 생각합니다 .

Magento documentation : "공장은 주사 불가능한 클래스, 즉 데이터베이스 엔티티를 나타내는 모델을 인스턴스화하는 서비스 클래스입니다. ObjectManager와 비즈니스 코드 사이에 추상화 계층을 만듭니다."

Alan Storm의 기사 : "저장소 객체는 객체 정보를 객체 저장소에 읽고 쓰는 역할을합니다"

나의 해석은 : 우리의 목적이 주사 불가능한 ( "신규") 객체를 다루는 것이라면 팩토리를 사용해야한다. 객체 저장소 내에서 객체 검색 / 읽기 / 쓰기에 중점을 둔 경우 리포지토리를 사용해야합니다.

이것이 주제에 대한 나의 이상 주의적 접근이다. Alan이 지적한 것처럼 실제 구현으로 인해 문제가 발생할 수 있습니다.

즐겨.


5

데이터 리딩 / 라이팅과 비즈니스 로직 간의 코드 분리를 허용하므로 리포지토리를 사용하기 시작하는 방법이 앞으로 나아갈 것이라고 말하고 싶습니다.

Alan Storm이 작성한 리포지토리 사용 방법을 설명하고이 새로운 방법의 단점을 살펴 보는 매우 자세한 기사가 있습니다. http://alanstorm.com/magento_2_understanding_object_repositories/

또한 Magento 설명서에서이 새로운 어프로치의 이점을 설명합니다. http://devdocs.magento.com/guides/v2.0/extension-dev-guide/service-contracts/service-contracts.html


2
답변 해주셔서 감사합니다. 나는 실제로 alanstorm의 기사에서 내 머리 에이 의심을 얻습니다. :)
Rajeev K Tomy

3
실제로, 그것은 당신을 생각하게하지만, 아마도 좋은 것입니다. 이것이 Magento가 제안한 모범 사례 라하더라도 개발자가 질문을 제기하고 그 일부를 비판 할 수는 없습니다. 또한 저장소에 포함되지 않은 상황이 여전히 있습니다. 그러나 리포지토리를 사용하여 향후 릴리스에서 중단되지 않는 확장 기능을 구축 할 때는 고려해야합니다. 또한 개발자들이 더 개발하고 개발자가 필요로하는 것에 대해 더 많은 정보를 제공 할 것이라고 확신합니다.
Marina Vilcea

귀하의 의견에 100 % 동의합니다. 나는 정말로 그렇게 희망한다. fabian의 답변도 참조하십시오.
Rajeev K Tomy

예, 나는 이미 그의 대답을 상향 조정하는 것을 보았다. 좋은 질문 감사합니다!
Marina Vilcea

또한, 내가 읽은 어딘가에 낮은 수준의 데이터 조작 방법을 사용하여 설치 / 업그레이드 스크립트 괜찮다는 것을 $setup->updateTableRow(...);또는 공장, 잘 모르겠어요하지만 높은 수준뿐만 아니라 그 지역에 적용되는 사용하기위한 인수 느낌, 당신은 어떻게 생각하십니까?
medmek

1

이 답변이 다른 확장 개발자에게도 도움이되기를 바랍니다.

리포지토리 만 사용하여 모델을 저장해야합니다.

  1. Magento 2의 팩토리 모델은 매우 제한된 데이터를 보유합니다.
  2. 반면, 리포지토리 모델에는 고객, 제품 등과 관련된 eav 특성의 경우 모든 데이터가 포함됩니다.
  3. 모델 저장의 경우 항상 저장소를 사용하여 엔티티를 저장하십시오. 팩토리 모델이 모델 저장에 사용되는 경우 해당 엔티티와 관련된 모든 비 시스템 eav 속성 (고객, 제품 등)이 삭제됩니다.

  4. 모델로드를 위해 getById () 메소드를 사용하여 모델을 가져 오는 가장 좋은 방법은 리포지토리입니다.

모델 저장 목적으로 가능한 한 많이 리포지토리를 사용하는 것이 좋습니다.


1

이제로드, 저장, 삭제 메소드 (모델)는 더 이상 사용되지 않습니다. 따라서 자원 모델 또는 저장소를 사용할 수 있습니다.

Magento는 이제 저장, 삭제,로드 작업을 위해 엔티티 관리자 개념을 사용합니다.

자원 모델에는 이러한 조작을 수행하기위한 엔티티 관리자 오브젝트가 있습니다.

$categoryModel = $this->_objectManager->create('\Magento\Catalog\Model\CategoryFactory')->create();        
  $categoryResource = $this->_objectManager->create('\Magento\Catalog\Model\ResourceModel\Category');        
  $categoryResource->load($categoryModel, 3);        
  echo $categoryModel->getName();
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.