Magento的工厂模式

工厂模式是一个在软件设计中使用得很频繁的一设计模式,他归属创建模式。所谓工厂就是生产东西的地方,比如玩具厂生产玩具,农场生成水果/蔬菜等等。下面我们先学习或者复习一下工厂这种设计模式,我们以农场中的农民生产水果和蔬菜为例进行分析.
我们先定义一个产品抽像类,是所有产品的基类,我特地在这里加了__get/__set两个魔术方法,因为他在Magento中的Varien_Object也定义了这两个方法,这两个方法在一些框架经常使用到,如yii.这两个方法很好用,不像java了,要定义很多set/get方法。

代码块1:

abstract class Product
{
    private $_data = array();
    public function __set($var, $value){
        $this->_data[$var] = $value;
    }

    public function __get($var){
        if (isset($this->_data[$var])) {
            return $this->_data[$var];
        }
        return false;
    }
}
代码块2:水果的定义

class Fruit extends Product{
    //方法或者变量定义
}
代码块3:蔬菜的定义

class Vegetables extends Product{
    //方法或者变量定义
}
假设我们农场为了节约成本只有一个农民,而且刚开张只生产苹果和萝卜,那他又生产菜果,又生产萝卜.
菜果类:代码块2.1

class Apple extends Fruit {
    //方法或者变量定义
}
萝卜类:代码块3.1

class Radish extends Vegetables {
    //方法或者变量定义
}
代码块4:农场的定义,他的方法farmerAll相当一个农民

class Farm
{
    public static function farmerAll($productType) {
        if ('fruit' == $productType) {
            $fruit = new Apple ();
            return $fruit;
        } else if ('vegetables' == $productType) {
            $vegetables = new Radish();
            return $vegetables;
        } else {
            echo '暂不生产';
            return false;
        }
    }
}
现在来了一个客户买,他必须经过农场的农民来买,不然是就算偷菜了,呵呵。
代码如下:代码块5

$fruit = Farm::farmerAll('fruit');
$vegetables = Farm::farmerAll('vegetables');
农场发展了,决定专业化生产,一个农民生产一种产品,那么农场的定义发生变化:
代码块6:

class Farm {
    public static function farmerFruit() {
        $fruit = new Apple();
        return $fruit;
    }
    public static function farmerVegetables() {
        $vegetables = new Radish();
        return $vegetables;
    }
}
现在来了一个客户买,他找到相应的农民进行。
代码块7:

$fruit = Farm::farmerFruit();
$vegetables = Farm::farmerVegetables();
因为农场只生产菜果和萝卜,所以客户买的时候不要指明是那种水果和蔬菜,现在农场 发展了,准备再生产香蕉和白菜,类如下
香蕉类:代码块2.2

class Banana extends Fruit {
    //方法或者变量定义
}
白菜类:代码块3.2

class Cabbage extends Vegetables{
    //方法或者变量定义
}
但是为了成本考察不再追加农民.那么水果农民将生产两种水果,蔬菜农民生产两种蔬菜,此时,外界客户来买必须指定要那一种,不然农民会搞不清给那种给客户(只有一种时只能给那一种,呵呵)。此时的农场类变成了:
代码块8:

class Farm {
    public static function farmerFruit($fruitType) {
        if ('apple' == $fruitType) {
            $apple = new Apple();
            return $apple;
        }else if ('banana' == $fruitType) {
            $banana = new Banana();
            return $banana;
        }else {
            echo '暂不生产';
        return false;
        }
    }
    public static function farmerVegetables($vegetablesType) {
        if ('radish' == $vegetablesType) {
            $radish = new Radish();
            return $radish;
        }else if ('cabbage' == $vegetablesType) {
            $cabbage = new Cabbage();
            return $cabbage;
        }else {
            echo '暂不生产';
            return false;
        }
    }
}
我们已一个农场的发展,分析了工厂模式。在这个工厂模式中他有两类产品,由两个工厂方法来生产这两类产品。

XML与工厂模式

现在公司再次发展,需要再增加一个水果和蔬菜,那么我们再增加两个产品类,同时我们要修改农场中的两个工厂方法(农民),这与开闭原则是不相符的。
所以在这里我们引与xml文件,来处理这个问题。
代码块9:

<?xml version="1.0"?>
<config>
    <fruits>
        <apple >
            <file>test/apple.php</file>
        </apple>
        <banana >
            <file>test/banana.php</file>
        </bananagt>
    </fruits>
    <vegetables>
        <radish >
            <file>test/radish.php</file>
        </radish>
        <cabbage>
            <file>test/cabbage.php</file>
        </cabbagegt>
    </vegetables>
</config>
上面xml表示有两类产品下都有两个产品,其file节点表示产品类存在那个地方。如果此节点为空,则不引入。apple/banana这类节点表示类名,要把第一个字母输入为大写就可以了。现在我们来修改一下农场类.
代码块10:

class Farm {
    public static function getClassName($type) {
        //通过file_get_contents得到xml文件内容
        //通过simplexml_load_string解析xml文件
        //根据$type 找到file文件并include.
        //return 类名
    }
    public static function farmerFruit($fruitType) {
        $className = self::getClassName('fruit/' . $fruitType);
        return new $className();
    }
    public static function farmerVegetables($vegetablesType) {
        $className = self::getClassName('vegetables/' . $vegetablesType);
        return new $className();
    }
}

在这里我并没有写全getClassName,读者可以自行完成,当作一个练习。
这样当要再增加两个产品类时,我们不要修改农场类,只要在xml中加入节点就,农民就知道要生产他了。这样在没有修改源程序的情况下(当然修改了配置文件)实现了系统的扩展。同时由于类名是从getClassName统一生成的,所以以后要增强功能,也可以只修改这个方法就可以了。

在很多框架的工厂模式的应用都使用xml文件,如spring等。下面我们进入我们的Magento中是怎样应用的。

Magento工厂的应用
1、找出Magento中的产品分类。有如下几类:
Helper/model/resourceModel/block
2、Magento谁充当农场类? 由Mage.php中的Mage类充当。
3、谁充当农民?
helper的农民:由helper方法充当
model的农民:由getModel/getSingleton(单例)充当
resourceModel的农民:由getResourceModel/getResourceSingleton(单例)充当
block的农民:由getBlockSingleton(单例)充当,这个农民把生产的任务分给了Mage_Core_Model_Layout的getBlockSingleton农民.
Block还有一个农场类叫:Mage_Core_Model_Layout,里面的农民是:createBlock/getBlockSingleton.
4、xml的应用:
helper 的xml:
代码块11:

<helpers>
    <homepage>
    <class>Youthor_Homepage_Helper</class>
    </homepage>
</helpers>
取得一个helper产品对象$helper = Mage::helper(‘homepage/data’); 相当于找helper节点下的homepage节点,只不过返回的类名是class值加上data,如:Youthor_Homepage_Helper_Data(记得把data第一个字母大写),这与我们分析中的那个xml文件有一点不一样,但原理是一样的,不过这里的文件是根据类名自动引入的。如果是这样$helper = Mage::helper(‘homepage/homepage_test’),那么类名是Youthor_Homepage_Helper_Homepage_Test.由于Magento是基于Zend Frame的,所以它的类名同时表示了他的类文件所在的文件夹和类文件名,Youthor/Homepage/Helper/Homepage/Test.php有了这个规则,Magento才知道自动引入那个文件,以上的分析对model/resourceModel/block同样实用。

block的的xml:

<blocks>
    <homepage>
    <class>Youthor_Homepage_Blcok</class>
    </homepage>
</blocks>

取得一个block产品对象$block = Mage::getBlockSingleton(‘homepage/test’);

model/resourceModel的的xml:

<models>
    <homepage>
    <class>Youthor_Homepage_Model</class>
    <resourceModel>homepage_mysql4</resourceModel>
    </homepage>
    <homepage_mysql4>
    <class>Youthor_Homepage_Model_Mysql4</class>
    </homepage_mysql4>
</models>

取得一个model产品对象$model = Mage::getModel(‘homepage/test’); 取得单例model对象:$model = Mage::getSingleton(‘homepage/test’);

取得资源model,$resourceModel = Mage::getResourceModel(‘homepage/test’); 取得单例资源model对象:$resourceModel= Mage::getResourceSingleton(‘homepage/test’); 资源model的类名为Youthor_Homepage_Model_Mysql4_Test,它是从homepage找到homepage节点从而找到resourceModel节点的值homepage_mysql4,再由homepage_mysql4找到homepage_mysql4节点下的class节点的值Youthor_Homepage_Model_Mysql4再加上test(记得第一个字母大写)。

在工厂方法的第一个参数的/前的那个值 相应产品类型下的一个节点,(如homepage),在magento中一般认为是模块名,其实这不是必须的,他只是一个标示工厂方法怎样来找这个节点的名称而已,只要与你的工厂方法的第一个参数的/前的那个值相同就可以了,只不过在Magento中最好与模块名一致.

内容概要:本文详细介绍了一个基于JavaVue的联邦学习隐私保护推荐系统的设计与实现。系统采用联邦学习架构,使用户数据在本地完成模型训练,仅上传加密后的模型参数或梯度,通过中心服务器进行联邦平均聚合,从而实现数据隐私保护与协同建模的双重目标。项目涵盖完整的系统架构设计,包括本地模型训练、中心参数聚合、安全通信、前后端解耦、推荐算法插件化等模块,并结合差分隐私与同态加密等技术强化安全性。同时,系统通过Vue前端实现用户行为采集与个性化推荐展示,Java后端支撑高并发服务与日志处理,形成“本地训练—参数上传—全局聚合—模型下发—个性化微调”的完整闭环。文中还提供了关键模块的代码示例,如特征提取、模型聚合、加密上传等,增强了项目的可实施性与工程参考价值。 适合人群:具备一定JavaVue开发基础,熟悉Spring Boot、RESTful API、分布式系统或机器学习相关技术,从事推荐系统、隐私计算或全栈开发方向的研发人员。 使用场景及目标:①学习联邦学习在推荐系统中的工程落地方法;②掌握隐私保护机制(如加密传输、差分隐私)与模型聚合技术的集成;③构建高安全、可扩展的分布式推荐系统原型;④实现前后端协同的个性化推荐闭环系统。 阅读建议:建议结合代码示例深入理解联邦学习流程,重点关注本地训练与全局聚合的协同逻辑,同时可基于项目架构进行算法替换与功能扩展,适用于科研验证与工业级系统原型开发。
源码来自:https://pan.quark.cn/s/a4b39357ea24 遗传算法 - 简书 遗传算法的理论是根据达尔文进化论而设计出来的算法: 人类是朝着好的方向(最优解)进化,进化过程中,会自动选择优良基因,淘汰劣等基因。 遗传算法(英语:genetic algorithm (GA) )是计算数学中用于解决最佳化的搜索算法,是进化算法的一种。 进化算法最初是借鉴了进化生物学中的一些现象而发展起来的,这些现象包括遗传、突变、自然选择、杂交等。 搜索算法的共同特征为: 首先组成一组候选解 依据某些适应性条件测算这些候选解的适应度 根据适应度保留某些候选解,放弃其他候选解 对保留的候选解进行某些操作,生成新的候选解 遗传算法流程 遗传算法的一般步骤 my_fitness函数 评估每条染色体所对应个体的适应度 升序排列适应度评估值,选出 前 parent_number 个 个体作为 待选 parent 种群(适应度函数的值越小越好) 从 待选 parent 种群 中随机选择 2 个个体作为父方母方。 抽取父母双方的染色体,进行交叉,产生 2 个子代。 (交叉概率) 对子代(parent + 生成的 child)的染色体进行变异。 (变异概率) 重复3,4,5步骤,直到新种群(parentnumber + childnumber)的产生。 循环以上步骤直至找到满意的解。 名词解释 交叉概率:两个个体进行交配的概率。 例如,交配概率为0.8,则80%的“夫妻”会生育后代。 变异概率:所有的基因中发生变异的占总体的比例。 GA函数 适应度函数 适应度函数由解决的问题决定。 举一个平方的例子。 简单的平方问题 求函数的最小值,其中每个变量的取值区间都是 [-1, ...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值