In object oriented programming, a factory method is a method that’s used to instantiate an object. Factory methods exist to ensure system developers have control over how a particular object is instantiated, and how its arguments are passed in. There’s a certain school of though that thinks direct use of the new keyword in programming

  1. $object = new Foo;

is an anti-pattern, as directly instantiating an object creates a hard coded dependency in a method. Factory methods give the system owner the ability to control which objects are actually returned in a given context.

A factory object serves a similar purpose. In Magento 2, each CRUD model has a corresponding factory class. All factory class names are the name of the model class, appended with the word “Factory”. So, since our model class is named

  1. Pulsestorm/ToDoCrud/Model/TodoItem

this means our factory class is named

  1. Pulsestorm/ToDoCrud/Model/TodoItemFactory

To get an instance of the factory class, replace your block class with the following.

  1. #File: app/code/Pulsestorm/ToDoCrud/Block/Main.php
  2. <?php
  3. namespace Pulsestorm\ToDoCrud\Block;
  4. class Main extends \Magento\Framework\View\Element\Template
  5. {
  6. protected $toDoFactory;
  7. public function __construct(
  8. \Magento\Framework\View\Element\Template\Context $context,
  9. \Pulsestorm\ToDoCrud\Model\TodoItemFactory $toDoFactory
  10. )
  11. {
  12. $this->toDoFactory = $toDoFactory;
  13. parent::__construct($context);
  14. }
  15. function _prepareLayout()
  16. {
  17. var_dump(
  18. get_class($this->toDoFactory)
  19. );
  20. exit;
  21. }
  22. }

What we’ve done here is use automatic constructor dependency injection to inject a Pulsestorm\ToDoCrud\Model\TodoItemFactory factory object, and assign it to the toDoFactory object property in the constructor method.

  1. #File: app/code/Pulsestorm/ToDoCrud/Block/Main.php
  2. protected $toDoFactory;
  3. public function __construct(
  4. \Magento\Framework\View\Element\Template\Context $context,
  5. \Pulsestorm\ToDoCrud\Model\TodoItemFactory $toDoFactory
  6. )
  7. {
  8. $this->toDoFactory = $toDoFactory;
  9. parent::__construct($context);
  10. }

We also had to inject a block context object and pass that to our parent constructor. We’ll cover these context object in future articles, but if you’re curious about learning more, this quickies post is a good place to start.

In addition to injecting a factory into our block, we also added the following to our _prepareLayout method

  1. #File: app/code/Pulsestorm/ToDoCrud/Block/Main.php
  2. function _prepareLayout()
  3. {
  4. var_dump(
  5. get_class($this->toDoFactory)
  6. );
  7. exit;
  8. }

This will dump the toDoFactory‘s class name to the screen, and is a quick sanity check that our automatic constructor dependency injection worked. Reload your page with the above in place, and you should see the following

  1. string 'Pulsestorm\ToDoCrud\Model\TodoItemFactory' (length=41)

Next, replace your _prepareLayout method with this code

  1. #File: app/code/Pulsestorm/ToDoCrud/Block/Main.php
  2. function _prepareLayout()
  3. {
  4. $todo = $this->toDoFactory->create();
  5. $todo->setData('item_text','Finish my Magento article')
  6. ->save();
  7. var_dump('Done');
  8. exit;
  9. }

This code calls the create method of our factory. This will instantiate a \Pulsestorm\ToDoCrud\Model\TodoItemFactory object for us. Then, we set the item_textproperty of our model, and call its save method. Reload your page to run the above code, and then check your database table

  1. mysql> select * from pulsestorm_todocrud_todoitem\G
  2. *************************** 1. row ***************************
  3. pulsestorm_todocrud_todoitem_id: 1
  4. item_text: Finish my Magento article
  5. date_completed: NULL
  6. creation_time: NULL
  7. update_time: NULL
  8. is_active: 1
  9. 1 row in set (0.00 sec)

You’ll find that Magento has saved the information you requested. If you wanted to fetch this specific model again, you’d use code that looked like the following.

  1. #File: app/code/Pulsestorm/ToDoCrud/Block/Main.php
  2. function _prepareLayout()
  3. {
  4. $todo = $this->toDoFactory->create();
  5. $todo = $todo->load(1);
  6. var_dump($todo->getData());
  7. exit;
  8. }

Here we’ve used the factory to create our model, used the model’s load method to load a model with the ID of 1, and then dumped the model’s data using the various magic setter and getter methods available to a Magento 2 model.

  1. #File: app/code/Pulsestorm/ToDoCrud/Block/Main.php
  2. function _prepareLayout()
  3. {
  4. $todo = $this->toDoFactory->create();
  5. $todo = $todo->load(1);
  6. var_dump($todo->getData());
  7. var_dump($todo->getItemText());
  8. var_dump($todo->getData('item_text'));
  9. exit;
  10. }

Finally, if we wanted to use a CRUD model’s collection object, we’d use code that looked like this

  1. #File: app/code/Pulsestorm/ToDoCrud/Block/Main.php
  2. function _prepareLayout()
  3. {
  4. $todo = $this->toDoFactory->create();
  5. $collection = $todo->getCollection();
  6. foreach($collection as $item)
  7. {
  8. var_dump('Item ID: ' . $item->getId());
  9. var_dump($item->getData());
  10. }
  11. exit;
  12. }

Again, this code uses a factory object to create a CRUD model object. Then, we use the CRUD model object’s getCollection method to fetch the model’s collection. Then, we iterate over the items returned by the collection.

Once instantiated via a factory, Magento 2’s CRUD models behave very similarly, if not identically, to their Magento 1 counterparts. If you’re curious about Magento 1’s CRUD objects, our venerable Magento 1 for PHP MVC Developers article may be of interest, as well as the Varien Data Collections article.

Where did the Factory Come From

You may be thinking to yourself — how did Magento instantiate a Pulsestorm/ToDoCrud/Model/TodoItemFactory class if I never defined one? Factory classes are another instance of Magento 2 using code generation (first covered in our Proxy objectarticle). Whenever Magento’s object manager encounters a class name that ends in the word Factory, it will automatically generate the class in the var/generation folder if the class does not already exist. You can see your generated factory class at the following location

  1. #File: var/generation/Pulsestorm/ToDoCrud/Model/TodoItemFactory.php
  2. <?php
  3. namespace Pulsestorm\ToDoCrud\Model;
  4. /**
  5. * Factory class for @see \Pulsestorm\ToDoCrud\Model\TodoItem
  6. */
  7. class TodoItemFactory
  8. {
  9. //...
  10. }

Magento 2 Factory Objects的更多相关文章

  1. Magento 2 instantiate object by Factory Objects

    magento2的Factory Objects是用来实例化non-injectable classes,目前还不知道什么叫non-injectable classes. 可以用它来实例化Helper ...

  2. 时隔3年半Spring.NET 2.0终于正式Release了

    一直很喜欢Spring.NET,不过2011年8月2日1.3.2正式release之后,再没有正式版本的release了. 直到4天前,Spring.NET 2.0 GA终于Release. http ...

  3. IBM MQ 与spring的整合

    文件名:applicationContext-biz-mq.xml 新浪博客把里面的代码全部转换成HTML了,所以无法粘贴 可以查看CSDN里面的:http://blog.csdn.net/xiazo ...

  4. spring监听与IBM MQ JMS整合

    spring xml 的配置: 文件名:applicationContext-biz-mq.xml <?xml version="1.0" encoding="UT ...

  5. Core J2EE Patterns - Service Locator--oracle官网

    原文地址:http://www.oracle.com/technetwork/java/servicelocator-137181.html Context Service lookup and cr ...

  6. Object Pascal中文手册 经典教程

    Object Pascal 参考手册 (Ver 0.1)ezdelphi@hotmail.com OverviewOverview(概述)Using object pascal(使用 object p ...

  7. Cannot locate factory for objects of type DefaultGradleConnector, as ConnectorServiceRegistry has been closed.

    现象:更换android studio libs文件夹下的jar包,重新编译代码报错:Cannot locate factory for objects of type DefaultGradleCo ...

  8. Android Studio: Error:Cannot locate factory for objects of type DefaultGradleConnector, as ConnectorServiceRegistry

    将别人的项目导入自己的环境下出现的问题. Gradle refresh failed; Error:Cannot locate factory for objects of type DefaultG ...

  9. 深入浅出设计模式——抽象工厂模式(Abstract Factory)

    模式动机在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方法.但是有时候我们需要一个工厂可 ...

随机推荐

  1. Object#wait()与Object#wait(long)的区别

    例子 例1 最基础的等待-通知 下面一个例子,一个线程"waiting"在同步代码块调用了Object#wait()方法,另一个线程"timedWaiting" ...

  2. laravel 缓存相关常用操作

    //----------设置缓存----------- //Cache::put($key,$val,$minutes); 如果$key已存在,则覆盖原有值 Cache::put('name', '张 ...

  3. PHP xml_set_processing_instruction_handler() 函数

    定义和用法 xml_set_processing_instruction_handler() 函数规定当解析器在 XML 文档中找到处理指令时被调用的函数. 处理指令包含在 <? 和 ?> ...

  4. day5.流程控制及while单项循环

    一.判断类型 isinstance 1.语法 """ 语法: # 用法一 isinstance(要判断的值,要判断的类型) 返回True 或者 False # 用法二 i ...

  5. 《国际化Web项目测试:记第一次兼职测试的经历(一)》

    疫情期间我一直在家远程办公,无意间接到了个做测试兼职的机会.在不耽搁本职工作的情况下,我从今年五月份开启了主职和副职的并行的状态.这种项目经历对于我来说算是一次全新的体验,当然也真是累的够呛.到目前为 ...

  6. 学学Viewbinding

    Viewbinding 1.环境需求 环境上,需要Android Studio 3.6 Canary 11+ 同样的Gradle也需要升级(这年头都4.0了,应该没有还在用低版本的了吧...) 2.配 ...

  7. 100% 展示 MySQL 语句执行的神器-Optimizer Trace

    在上一篇文章<用Explain 命令分析 MySQL 的 SQL 执行>中,我们讲解了 Explain 命令的详细使用.但是它只能展示 SQL 语句的执行计划,无法展示为什么一些其他的执行 ...

  8. 什么才是定制化IDE的核心价值?

    写在前面 自 2018 年初,就与 VSCode 结下了不解之缘,从一份选型报告开始,一蹉跎就是 2 年多 期间反复思索着一个挥之不去的问题:定制化 IDE 产品的核心价值是什么? 事实上,答案并不唯 ...

  9. css实现折扇效果

    总结思路: 1.首先进行结构的书写   <div class="box"></div> 2.要进行图片的重叠要用到position定位,需要重叠的元素及子元 ...

  10. Solon 最简单demo---Hello World

    Solon 的项目地址: https://gitee.com/noear/solon 里面杂七杂八的东西很多...今天的目标是整一个最最简单,最最小巧的 Hello world (一)用 Intell ...