Khi nào chúng ta nên sử dụng Kho lưu trữ và Nhà máy trong Magento 2?


75

Tôi đã trải qua một vài hướng dẫn trong Magento 2, và điều này làm tôi bối rối một chút. Tôi có thể thấy về cơ bản có hai cách để chúng ta có thể đọc / ghi các thực thể kinh doanh:

Khôi phục dữ liệu

Sử dụng phương pháp tiếp cận nhà máy

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

Sử dụng phương pháp lưu trữ

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

Lưu dữ liệu

Sử dụng phương pháp tiếp cận nhà máy

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

Sử dụng phương pháp lưu trữ

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

Tôi cũng có thể thấy rằng, cả kho lưu trữ và lớp nhà máy đều có thể được tiêm bằng cách sử dụng phép nội xạ phụ thuộc. Điều này ít gây nhầm lẫn cho tôi.

Khi nào chúng ta nên sử dụng cách tiếp cận kho lưu trữ và cách tiếp cận nhà máy? Thực hành tốt nhất chúng ta cần phải làm theo là gì?


Một ví dụ điển hình về việc sử dụng Factory, CollectionFactory và Kho lưu trữ có thể được nhìn thấy trên \ Magento \ Setup \ Fixture \ CategoryResolver
Ricardo Martins

Câu trả lời:


72

Nếu có một kho lưu trữ và nó làm những gì bạn cần, hãy luôn thích kho lưu trữ.

Các kho lưu trữ là một phần của Hợp đồng dịch vụ (chúng là các triển khai của các giao diện Api), điều này có nghĩa là chúng có nghĩa là một giao diện chung cho các mô-đun khác.

Sử dụng kho để tải đầy đủ

$model->load()không phải là một phần của hợp đồng dịch vụ. Tôi đã có một câu hỏi về chủ đề cụ thể đó, bạn có thể thấy câu trả lời hữu ích: Có bao giờ lý do để thích $ model-> load () hơn các hợp đồng dịch vụ không?

Sử dụng các nhà máy để tạo các thực thể mới

Các kho lưu trữ không đi kèm với các phương thức để tạo ra một thực thể mới, vì vậy trong trường hợp đó, bạn sẽ cần một nhà máy. Nhưng sử dụng nhà máy cho giao diện , chẳng hạn như Magento\Catalog\Api\Data\ProductInterfaceFactory- nó sẽ tạo ra việc thực hiện đúng dựa trên cấu hình DI.

Sau đó sử dụng repository->save()phương pháp để lưu nó.

Sử dụng Bộ sưu tập các nhà máy nếu bạn cần kiểm soát nhiều hơn

Dưới đây không phải là thực hành tốt nhất của Magento, nhưng hiện tại, các kho lưu trữ không cung cấp cho bạn quyền kiểm soát tốt đối với những gì cần tải. API tiêu chí tìm kiếm cho phép bạn xác định các bộ lọc, nhưng ví dụ: không có cách nào để chọn các thuộc tính EAV cụ thể hoặc chỉ định bảng chỉ mục nào sẽ tham gia.

Đây là các chi tiết triển khai, được ẩn khỏi các API hợp đồng dịch vụ, nhưng thường các chi tiết triển khai này quan trọng và bạn sẽ có hiệu suất kém nếu bạn bỏ qua chúng. Vì lý do đó, ngay khi các kho lưu trữ đang giới hạn tôi, tôi không ngần ngại sử dụng các bộ sưu tập cơ bản nữa.


2
Bạn có thể đưa ra một ví dụ mã về việc sử dụng Các nhà máy để tạo các thực thể mới , phần giải thích bỏ lỡ một số chi tiết và khó hiểu. Cảm ơn rât nhiều.
Khóa Thương


Cảm ơn. nhưng use the factory for the interface, such as Magento\Catalog\Api\Data\ProductInterfaceFactory - it will create the right implementation based on DI configuration.điểm mà tôi không thể hiểu được, các hướng dẫn dev không giới thiệu InterfaceFactory , làm thế nào để sử dụng repository->save()phương thức để lưu các thực thể mới? Tôi chỉ có thể sử dụng nhà máy để lưu các thực thể mới, không lưu trữ.
Khóa Thương

@Key Shang, điều đó có nghĩa là giao diện sẽ cung cấp cho bạn tất cả các hàm dữ liệu được đặt để lưu từng cột trong bảng, vì vậy hãy thử sử dụng giao diện bất cứ nơi nào có thể để lưu bản ghi mới. Các lớp InterfaceFactory được tạo như một phần của di: compile để bạn có thể thấy chúng trong thư mục var / Generation.
stevensagaar

@stevensagaar Cảm ơn, tôi có thể hiểu nó ngay bây giờ.
Khóa Shang

21

Câu hỏi hay.

Ngay cả khi cả Kho và Nhà máy cho phép chúng tôi truy cập vào một Thực thể tôi nghĩ chúng ta nên tập trung vào trách nhiệm của họ .

Từ tài liệu Magento : "Các nhà máy là các lớp dịch vụ khởi tạo các lớp không thể tiêm, nghĩa là các mô hình đại diện cho một thực thể cơ sở dữ liệu. Chúng tạo ra một lớp trừu tượng giữa ObjectManager và mã doanh nghiệp."

Từ bài viết của Alan Storm : "Một đối tượng lưu trữ chịu trách nhiệm đọc và ghi thông tin đối tượng của bạn vào kho lưu trữ đối tượng"

Giải thích của tôi là: Nếu mục đích của chúng tôi là làm việc với các đối tượng không thể tiêm (được gọi là "mới có thể"), chúng tôi nên sử dụng Factories; nếu chúng ta tập trung vào việc tìm kiếm / đọc / ghi đối tượng trong một kho đối tượng thì chúng ta nên sử dụng Kho lưu trữ.

Đây là cách tiếp cận lý tưởng của tôi đối với chủ đề này; Hãy nhớ rằng việc thực hiện thực tế có thể buộc chúng ta phải làm rối tung mọi thứ, như Alan đã chỉ ra.

Thưởng thức.


5

Tôi muốn nói rằng cách chuyển tiếp là bắt đầu sử dụng các kho lưu trữ vì chúng cho phép phân tách mã giữa đọc / ghi dữ liệu và logic kinh doanh.

Có một bài viết rất chi tiết được viết bởi Alan Storm về điều này, giải thích cách sử dụng kho lưu trữ nhưng cũng xem xét một số nhược điểm của phương pháp mới này: http://alanstorm.com/magento_2_under Hiểu_object_Vpos khu /

Ngoài ra, từ tài liệu Magento, giải thích các lợi ích của aproach mới này: http://devdocs.magento.com/guides/v2.0/extension-dev-guide/service-contuces/service-contuces.html


2
cảm ơn vì câu trả lời Tôi thực sự nhận được nghi ngờ này trên đầu từ bài báo của alanstorm. :)
Rajeev K Tomy

3
Thật vậy, nó khiến bạn suy nghĩ, nhưng đó có lẽ là một điều tốt. Ngay cả khi đây là cách thực hành tốt nhất được đề xuất bởi Magento, điều đó không có nghĩa là các nhà phát triển không thể đưa ra câu hỏi và phê bình một số khía cạnh của nó. Ngoài ra, vẫn có những tình huống không được lưu trữ trong kho. Tuy nhiên, trong bối cảnh xây dựng các tiện ích mở rộng không phá vỡ các bản phát hành trong tương lai bằng cách sử dụng kho lưu trữ nên được xem xét. Ngoài ra, tôi chắc chắn họ sẽ phát triển hơn nữa và cung cấp bảo hiểm nhiều hơn về những gì nhà phát triển cần.
Bến du thuyền Vilcea

Tôi 100% đồng ý với nhận xét của bạn. Tôi thực sự hy vọng như vậy. Ngoài ra xin vui lòng xem câu trả lời của fabian quá.
Rajeev K Tomy

Vâng, tôi đã thấy :) đã nâng cao câu trả lời của mình. Cảm ơn vì câu hỏi tuyệt vời của bạn!
Bến du thuyền Vilcea

Hơn nữa, tôi đọc được ở đâu đó rằng sử dụng phương pháp thao tác dữ liệu cấp thấp hơn là ổn trong cài đặt / nâng cấp tập lệnh $setup->updateTableRow(...);hoặc nhà máy, tôi không chắc nhưng cảm giác như các đối số sử dụng cấp cao hơn cũng áp dụng cho khu vực đó, bạn nghĩ sao?
medmek

1

Hy vọng câu trả lời này có thể giúp các nhà phát triển mở rộng khác là tốt.

Chúng ta phải lưu mô hình chỉ sử dụng Kho lưu trữ.

  1. Mô hình nhà máy trong Magento 2 giữ dữ liệu rất hạn chế.
  2. Mặt khác, Mô hình Kho lưu trữ chứa tất cả dữ liệu, trong trường hợp các thuộc tính eav liên quan đến khách hàng, sản phẩm, v.v.
  3. Để lưu mô hình, luôn sử dụng Kho lưu trữ để lưu bất kỳ thực thể nào, nếu mô hình nhà máy được sử dụng để lưu mô hình, nó sẽ xóa tất cả các thuộc tính eav không thuộc hệ thống liên quan đến thực thể đó (khách hàng, sản phẩm, v.v.).

  4. Đối với mục đích tải mô hình, Kho lưu trữ là tùy chọn tốt nhất để lấy mô hình bằng phương thức getById ().

Tôi sẽ khuyên bạn nên sử dụng Kho lưu trữ càng nhiều càng tốt đặc biệt cho mục đích lưu mô hình.


1

Bây giờ tải, lưu, xóa phương thức (mô hình) không được dùng nữa. Vì vậy, chúng ta có thể sử dụng mô hình tài nguyên hoặc kho lưu trữ.

Magento hiện đang sử dụng khái niệm trình quản lý thực thể để lưu, xóa, tải các hoạt động.

Các mô hình tài nguyên có đối tượng quản lý thực thể để thực hiện các hoạt động đó.

$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();
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.