Magento设计模式

Jon*_*onB 34 php design-patterns zend-framework magento

Magento,恕我直言,代表了一个基于深思熟虑的编码原则的PHP系统 - 可重用的设计模式就是其中之一.就PHP系统的一个例子而言,我认为它可以被认为是非常前沿的,因此从架构的角度来看值得考虑.

据我了解,OOP开发人员可以使用许多设计模式.看到在Magento这样的开源系统中使用的这些模式允许开发人员在实际使用和原位查看这些模式的示例,而不是在有时可能相当麻烦,甚至有点误导的示例中.

因此,我想知道除了下面列出的模式之外,Magento程序员在为Magento开发时使用了哪些模式.

作为一个注释,我理解这些模式中的一些是由于构建在Zend框架上的结果,MVC /前端控制器是其中的几个,

显而易见的是:

厂:

$product = Mage::getModel('catalog/product');
Run Code Online (Sandbox Code Playgroud)

辛格尔顿:

$category = Mage::getSingleton('catalog/session');
Run Code Online (Sandbox Code Playgroud)

注册地:

$currentCategory = Mage::registry('current_category');
Run Code Online (Sandbox Code Playgroud)

clo*_*eek 17

原型:

Mage:getModel('catalog/product')->getTypeInstance();
Run Code Online (Sandbox Code Playgroud)

事件 - 观察者对:

# PHP
Mage::dispatchEvent('event_name', array('key'=>$value));

# config.xml
<config>
    <global>
        <events>
            <event_name>
                <observers>
                    <unique_name>
                        <class>Class_Name</class>
                        <method>methodName</method>
                    </unique_name>
                </observers>
            </event_name>
        </events>
    </global>
</config>
Run Code Online (Sandbox Code Playgroud)

对象池:

$id = Mage::objects()->save($object);
$object = Mage::objects($id);
Run Code Online (Sandbox Code Playgroud)

迭代器:

Mage::getModel('catalog/product')->getCollection();
Run Code Online (Sandbox Code Playgroud)


Kam*_*ngi 15

详细介绍了Magento中的设计模式

  1. 模型视图控制器模式

模型视图控制器,简称MVC,是一种设计模式,其中业务,表示和耦合逻辑是分开的.Magento大量使用XML作为模板逻辑,并将HTML与PHP文件混合用于其视图.模型由Varien的ORM支持.大多数业务逻辑发生在模型中,而控制器将模型数据映射到视图.

因为Magento的视图"很胖" - 它们通常包含很多逻辑 - 视图中有一个额外的PHP类(Block系统)并不罕见,它将有助于渲染.

  1. 前控制器模式

前控制器模式确保只有一个入口点.调查所有请求,将其路由到指定的控制器,然后根据规范进行处理.前端控制器负责初始化环境并将请求路由到指定的控制器.

Magento只有一个入口点(index.php),它将初始化应用程序环境(Mage :: app())并将请求路由到正确的控制器.

  1. 工厂模式

正如名称所暗示的那样,工厂模式负责分解(实例化)类.它通过Magento代码库广泛使用,并利用Magento中的自动加载系统.通过在模块中为其config.xml定义别名,您可以让工厂知道它可以在哪里找到类.

Mage核心类中有各种工厂辅助方法,其中一个是getModel().它接受类的别名,然后返回它的实例.工厂模式不是通过代码库分散包含调用,而是以统一的方式实例化类.

  1. 单身模式

检索类实例的另一种方法是调用Mage :: getSingleton().它接受一个类别名,在返回一个实例之前,它会检查内部注册表是否已经实例化过该类 - 这会导致共享实例.这是强制性的一个例子是会话存储,它应该通过代码库共享,而不是每次都重新创建它.

  1. 注册表模式

所有单例都存储在内部注册表中:用于存储数据的全局范围容器.它不仅供内部使用.Mage :: register($ key,$ value),:: registry($ key)和:: unregister($ key)方法可以分别用于存储,检索和从注册表中删除数据.注册表通常用于在范围无法传递时在范围之间传输数据,否则.

  1. 原型模式

工厂模式(我们列表中的#3)停止的地方是原型模式继续的地方.它定义了类的实例可以根据其父类(原型)检索特定的其他类实例.一个值得注意的例子是Mage_Catalog_Model_Product类,它具有getTypeInstance方法,用于检索特定的Mage_Catalog_Model_Product_Type,其中包含不适用于所有产品的特定方法和属性子集.

例如,Mage_Downloadable_Model_Product_Type最终扩展了Mage_Catalog_Model_Product_Type.如果您正在迭代订单并想要调用可下载产品的特定方法,则需要首先使用原始产品的getTypeInstance方法对其进行分解.

  1. 对象池模式

对象池模式只是一个包含对象的框,因此不必一次又一次地分配和销毁它们.它在Magento中并没有被大量使用,除了资源很快就会受到限制的重任务,比如导入产品.可以使用Mage :: objects()访问对象池(由Varien_Object_Cache管理).

  1. 迭代器模式

迭代器模式定义了一种使用对象迭代容器的共享方法.在Magento中,这由Varien_Data_Collection处理,Varien_Data_Collection又使用各种带烘焙的PHP类(如ArrayIterator)来为数组提供更多的OO接口.这可确保模型集合始终具有公共API以进行迭代,而不依赖于实际模型.

  1. 延迟加载模式

延迟加载可确保加载数据延迟到实际需要时为止.这导致使用的资源更少.Magento的延迟加载行为之一就是收藏行为.如果您要使用Mage :: getModel('catalog/product') - > getCollection()检索产品集合,则只有在您实际访问集合时才会触及数据库,例如,迭代它或检索找到的模型数量.

  1. 服务定位器模式

服务定位器模式抽象出某个服务的检索.这允许在不破坏任何内容的情况下更改服务(因为它遵循其抽象基础),而且还可以获取适合其目的的服务.

Ryan用数据库连接举例说明了这一点.另一个例子是Magento的缓存机制,其中Mage :: getCache()是由Zend或其他供应商提供的缓存存储的代理服务定位器.

  1. 模块模式

熟悉Magento开发的人偶然发现了模块模式.它基本上定义了不同的域被分组为独立的模块,这些模块彼此独立地工作,并且可以根据需要插入到主系统中.在理想情况下,模块模式的实现将确保可以移除或交换每个元素.PHP中模块模式的主角之一是Composer包管理器.

虽然Magento严重依赖于模块化架构,但它并非模块化.某些功能与核心密切相关,无法轻易更改.还有超级全局Mage核心类的大量使用,它引入了不容易监视的各种系统范围的依赖关系.

  1. 观察者模式

Magento的事件驱动架构是观察者模式实现的结果.通过定义观察者(或监听器),可以挂钩额外的代码,当观察到的事件触发时,将调用这些代码.Magento使用其XML数据存储来定义观察者.如果使用Mage :: dispatchEvent($ eventName,$ data)触发事件,则将查询数据存储并触发$ event的相应观察者.


Jos*_*tey 7

还有一些:

事件/听众:

Mage::dispatchEvent('model_load_before', $params); 
Run Code Online (Sandbox Code Playgroud)

当然还有MVC,其中Views由XML,PHP类和PHTML模板组合表示.


dav*_*elo 6

不要忘记延迟加载,这意味着只有在严格必要时才会发生数据库访问.例如:

$collection_of_products = Mage::getModel('catalog/product')
->getCollection();
$collection_of_products->addFieldToFilter('sku','n2610');
Run Code Online (Sandbox Code Playgroud)

在您尝试访问Collection中的项目之前,不会进行数据库查询.