发表日期: 2021-04-27 08:54:14 浏览次数:177
邳州网站优化【邳州开通400电话】邳州网站搭建、邳州微信公众号推文外包、邳州开通京东拼多多设计、邳州淘宝装修
邳州,简称“邳”,江苏省徐州市代管县级市, [1-2] 古称良城、邳国、下邳、邳县,位于苏鲁交界,东接新沂市,西连徐州市铜山区、贾汪区,南界睢宁县,北邻山东省兰陵县。 [3] 1992年撤县设市。
邳州历史悠久,境内大墩子文化遗址距今6000年,是江苏文明最早的起源之一。境内有邳州市艾山风景名胜区、沙沟湖水杉公园、国家银杏博览园、小萝卜头纪念馆等旅游景点。邳州的城市精神是“创新、争先、开放、包容”。 [4]
邳州发展的目标是东陇海产业带重要的水陆交通枢纽、新兴工贸城市,京杭运河沿岸具有水乡特色和历史文化底蕴的生态宜居城市。
2019年7月,邳州入选国家知识产权强县工程试点县(区)。2019年,邳州位居全国综合实力百强县市第37位、经济竞争力百强第40位、全国投资潜力百强县市第18位、全国绿色发展百强县市第33位、全国科技创新百强县市第36位、全国新型城镇化质量百强县市第51位。
周营养计划推送
月计划推送
孕妇欢迎语推送
产后妈妈首次推送
针对宝宝的月推送
周报推送
孕妇周营养计划推送
更具有挑战性的是,每种推送的实现逻辑都异常复杂,但又存在一定程度上的相似性。当时,最初我看到产品整理的推送需求,是非常惊讶的。因为里面的规则非常细致,在惊叹产品经理有如此缜密思维的同时,我也在思考如何清晰地把这些规则准确无误去表达出来。第一时间想到的就是,对于如此复杂的领域问题,应该采用设计模式来解决。经过综合评估,模板方法是最为贴切的选择。
为了验证最终实现的效果,以及提高我们的关注点。先来编写一个单元测试用例。
// Family-2.0$ vim ./Apps/Scale/Tests/Domain/Domain_SPush_Week_Test.phpclass PhpUnderControl_DomainSPushWeek_Test extends PHPUnit_Framework_TestCase{
public $domainSPushWeek;
protected function setUp()
{
parent::setUp();
$this->domainSPushWeek = new Domain_SPush_Week();
}
public function testPush() {
DI()->notorm->spush_record->where('user_id', 187)->where("type like '%week%'")->delete();
$UUID = 'AAAD56B5460339234A4A2492680171A88818B96B8D8DA687FB';
$rs = $this->domainSPushWeek->push($UUID);
$this->assertSame(0, $rs);
}}复制代码上面是针对每周推送领域业务类的测试用例,先是清除了测试数据,然后重新进行推送,并验证返回的结果值为0。状态码为0表示成功,非0表示不同的失败原因。
每周推送领域业务类是一个具体的实现类,在这之前,我们需要实现公共推送领域业务基类。这个基类是实现扩展其他不同种类推送的关键,并且也是需要采用模板方法的设计。它维护了公共通用的流程步骤,但又允许实现子类进行定制和扩展。经过不断的努力和重构优化,并在单元测试驱动的指导下,最终此推送基类的实现代码如下:
// Family-2.0$ vim ./Apps/Scale/Domain/SPushBase.phpabstract class Domain_SPushBase {
/**
* 统一的推送模板方法
*/
public function push($UUID) {
$userId = Domain_User_Helper::UUID2UserId($UUID);
if ($userId <= 0) {
return 1;
}
$domainMotherInfo = new Domain_SMotherInfo();
$infoEx = $domainMotherInfo->getInfoEx($userId);
$infoEx['user_id'] = $userId;
if (empty($infoEx)) {
return 1;
}
//过滤不符合条件的用户
if (!$this->varidateInfo($infoEx)) {
return 2;
}
//过滤已有纪录的用户,以防重复推送
$domainPushReocrd = new Domain_SPush_Record();
if ($domainPushReocrd->hasPushBefore($userId, $this->getPushRecordType($infoEx))) {
return 3;
}
//找到绑定的称
$domainDevice = new Domain_Device_User();
$deviceList = $domainDevice->getList($userId, Model_Device::DEVICE_TYPE_SCALE);
if (empty($deviceList) || empty($deviceList[0]['binded_groups'][0]['group_id'])) {
DI()->logger->error('no device or no group for user when push week', array('userId' => $userId));
return 5;
}
$toPushWeekGroupId = $deviceList[0]['binded_groups'][0]['group_id']; //取第一个家庭组
//动态图片
$isPostFeed = $this->postFeed($userId, $infoEx, $toPushWeekGroupId);
if (!$isPostFeed) {
return 6;
}
//推送纪录
$domainPushReocrd->takeRecord($userId, $this->getPushRecordType($infoEx));
return 0;
}}复制代码从上面的Domain_SPushBase::push($UUID)接口签名可以看出,可以针对特定的用户进行不同种类的推送。在推送的过程中,会进行一系列的检测、判断和操作,例如用户是否满足条件,是否已被推送,是否绑定了相关的称设备,进行具体的推送,最后纪录推送的情况。如果这些未能进行统一控制,而是由每个业务类重复实现,不仅会导致代码上的重复,而且也难以保持业务流程上的一致性,从而缺乏对业务规则的统一管理。
Domain_SPushBase是一个抽象类,它有两个重要的抽象方法,分别是发布动态Domain_SPushBase::postFeed($userId, $infoEx, $toPushWeekGroupId)和获取推送纪录类型Domain_SPushBase::getPushRecordType($infoEx)。在实现具体的领域业务子类时,只需要实现这两个抽象方法即可。
abstract class Domain_SPushBase {
/**
* 验证用户是否满足推送的业务要求
*/
protected function varidateInfo($infoEx) {
return true;
}
/**
* 发布动态
*/
abstract protected function postFeed($userId, $infoEx, $toPushWeekGroupId);
/**
* 推送纪录类型
*/
abstract protected function getPushRecordType($infoEx);}复制代码注意到,在此推送基类里,还有一个可重载的方法,即验证用户是否满足推送的业务要求的类方法Domain_SPushBase::varidateInfo($infoEx),这一步是用于检测是否需要向用户进行推送。默认情况是满足条件。
认识了推送基类后,再回来看下如何在继承此基类的情况下,快速完成特定每周营养计划推送的业务逻辑。最终推送的信息,其展示效果如图6-8的设计稿所示。
