工厂模式——猫粮公司的演进蝉沐风的码场

陀螺是个程序喵,另起炉灶自己开了公司,为了纪念曾经码梦为生的岁月,公司起名为“跑码场”,主要业务是生产猫粮。

一个喵兼顾着研发和运营,终究不是长久之计。于是雇了一个菜喵做学徒,技术怎么样并不在意,陀螺最看重的是菜喵的名字—招财。

很快,第一款产品「鱼香猫粮」上线,陀螺让招财写个线上订单系统,方便顾客网上下单

招财很快写出了代码

/***鱼香味猫粮**@author蝉沐风*/publicclassFishCatFood{//猫粮口味privateStringflavor;//制作猫粮的工艺过程publicvoidmake(){System.out.println("正在制作【"+flavor+"】口味的猫粮");}publicStringgetFlavor(){returnflavor;}publicvoidsetFlavor(Stringflavor){this.flavor=flavor;}publicFishCatFood(Stringflavor){this.flavor=flavor;}}publicclassPaoMaChang{publicFishCatFoodorder(){FishCatFoodfishCatFood=newFishCatFood("fish");fishCatFood.make();returnfishCatFood;}}测试之后上线,一直运行正常。

招财接到任务,重构了原来的代码,首先创建了抽象的CatFood,之后所有具体口味的猫粮必须继承该类

/***猫粮的抽象类,所有具体口味的猫粮必须继承自该接口**@author蝉沐风*/publicabstractclassCatFood{//产品风味Stringflavor;publicabstractvoidmake();}接下来依次是各种口味的猫粮对象

/***牛肉猫粮*/publicclassBeefCatFoodextendsCatFood{publicBeefCatFood(){this.flavor="beef";}@Overridepublicvoidmake(){System.out.println("正在制作【beef】口味猫粮");}}/***鸡肉猫粮*/publicclassChickenCatFoodextendsCatFood{publicChickenCatFood(){this.flavor="chicken";}@Overridepublicvoidmake(){System.out.println("正在制作【chicken】口味猫粮");}}/***鱼香猫粮*/publicclassFishCatFoodextendsCatFood{publicFishCatFood(){this.flavor="fish";}@Overridepublicvoidmake(){System.out.println("正在制作【fish】口味猫粮");}}/***薄荷猫粮*/publicclassMintCatFoodextendsCatFood{publicMintCatFood(){this.flavor="mint";}@Overridepublicvoidmake(){System.out.println("正在制作【mint】口味猫粮");}}最后是下单的逻辑

publicclassPaoMaChang{publicCatFoodorder(Stringflavor){CatFoodcatFood;if("fish".equals(flavor)){catFood=newFishCatFood();}elseif("beef".equals(flavor)){catFood=newBeefCatFood();}elseif("mint".equals(flavor)){catFood=newMintCatFood();}elseif("chicken".equals(flavor)){catFood=newChickenCatFood();}else{thrownewRuntimeException("找不到该口味的猫粮");}catFood.make();returncatFood;}}招财迫不及待地向陀螺展示自己的代码,并介绍到:“老板,我的代码已经能够满足未来的动态变化了,如果再有新口味的产品,只需要创建该产品的对象,然后修改一下order()方法就好了!”

陀螺赞赏地点点头,“看得出来你经过了自己认真的思考,这一点非常好!但是别着急,你有没有听说过开闭原则?”

“开闭原则?听说过,但是仅仅停留在概念上,我记得好像是‘对修改关闭,对扩展开放’,当时为了面试背的还是挺熟的,哈哈哈”

“那你对照开闭原则再看一下你的代码,你觉得你的代码有什么问题?”,陀螺问道。

招财赶紧仔细审视了一下自己的代码,"我知道了,现在的问题是一旦有新产品上线,就需要改动orde()方法,这就是所谓的没有对修改关闭吧,但是有了新的产品你总得有个地方把他new出来啊,这一步是无论如何都无法省略的,我觉得目前的代码是能够满足需求的。"

“你说的没错,设计原则并不是金科玉律,比如未来如果只有零星几个的新口味产品上线的话,你确实没有必要改变现在的代码结构,简单的修改一下order()就可以了,根本不用在意对修改关闭的这种约束。但是你有必要思考一下,如果后期我们研发了数十种乃至上百种产品,这种情况下你该怎么做?”

“除了修改order()方法,我实在没有想出其他的办法...”,招财挠着脑袋回答道。

陀螺不急不慢地解释说:“这种时候,我们可以先识别出代码中哪些是经常变化的部分,然后考虑使用封装,很明显,order()方法中创建对象的部分就是经常需要变化的,我们可以将封装,使其专门用于创造对象。”

/***猫粮类的简单工厂*@author蝉沐风*/publicclassSimpleCatFoodFactory{publicstaticCatFoodcreateCatFood(Stringflavor){CatFoodcatFood;if("fish".equals(flavor)){catFood=newFishCatFood();}elseif("beef".equals(flavor)){catFood=newBeefCatFood();}elseif("mint".equals(flavor)){catFood=newMintCatFood();}elseif("chicken".equals(flavor)){catFood=newChickenCatFood();}else{thrownewRuntimeException("找不到该口味的猫粮");}returncatFood;}}/***重构之后的order代码*/publicclassPaoMaChangV2{publicCatFoodorder(Stringflavor){CatFoodcatFood=SimpleCatFoodFactory.createCatFood(flavor);catFood.make();returncatFood;}}陀螺解释说:“如此一来,我们完成了封装的操作,把生成对象的操作集中在了SimpleCatFoodFactory中。”

招财立即提出了自己的疑问:“我不理解这样做有什么好处,在我看来这只是把一个问题搬到了一个对象里罢了,问题本身依然存在!”

招财无奈地回应说,“好吧,你的话确实很有道理,把经常变动的部分提取出来是个不错的代码优化习惯。对了,刚才这种优化技巧有名字吗?”

“这种叫简单工厂,很多开发人员都误以为它是一种设计模式了,但是它其实并不属于GoF23种设计模式,但是由于用的人太多,经常把它和工厂模式一起介绍。至于是不是设计模式,对我们而言并不重要。”

简单工厂并不是一种设计模式,更像是一种编程的优化习惯,用来将对象的创建过程和客户端程序进行解耦

招财并不放弃,继续追问,“那能不能有个办法再优化一下创建对象的过程呢,它现在依然没有满足开闭原则!而且客户端的调用方式非常不优雅,万一参数不小心拼错了,直接就崩了,这种麻烦不应该转嫁到客户端不是吗?”

陀螺愣了愣,久久盯着招财,仿佛看到了当年自己刚学习编程的样子,对一切充满好奇,对代码又有点洁癖,欣慰地说道:“说得好啊,那我们尝试利用反射继续优化一下吧。”

/***反射优化后的猫粮类的简单工厂**@author蝉沐风*/publicclassSimpleCatFoodFactoryV2{publicstaticCatFoodcreateCatFood(Classclazz){if(clazz!=null){try{returnclazz.newInstance();}catch(Exceptione){thrownewRuntimeException("对象不存在");}}returnnull;}}客户端的代码优化如下

publicCatFoodorder(Classclazz){CatFoodcatFood=SimpleCatFoodFactoryV2.createCatFood(clazz);catFood.make();returncatFood;}“到此SimpleCatFoodFactoryV2就符合了开闭原则,但是这里利用反射的一个基本原则是所有对象的构造方法必须保持一致,如果对象创建的过程比较复杂而且各有特点,那么优化到这一步或许并不是最好的选择,记住优化的原则——合适就好”,陀螺补充道。

招财对陀螺的这一番优化和解说佩服不已,心想实习遇到这么个好老板好师傅,平时还能试吃自己最爱的猫粮,这简直就是在天堂啊。

但是不同的分公司需要根据当地特色生产不同口味的产品,比如山东生产「葱香猫粮」、「大酱猫粮」,湖南生产「辣子猫粮」、「剁椒猫粮」...

招财心想,这不简单嘛!继续利用SimpleCatFoodFactoryV2,让各个公司的新款猫粮继承CatFood不就可以了嘛!

但是转念一想,随着每个分公司的产品链的丰富,获取产品的创建过程会有差异,那么SimpleCatFoodFactoryV2的职责会变得越来越多,像一个万能的类,不方便维护。

招财想到可以为每个分公司创建独立的简单工厂,然后将具体的简单工厂对象绑定到PaoMaChang对象中,顾客下单的时候只要指定对应的分公司的工厂和口味就可以进行下单了。

PaoMaChangV3重构如下

/***跑码场对象-版本3*@author蝉沐风*/publicclassPaoMaChangV3{privateICatFoodFactoryfactory;publicPaoMaChangV3(ICatFoodFactoryfactory){this.factory=factory;}publicCatFoodorder(Stringflavor){CatFoodcatFood=factory.create(flavor);catFood.make();returncatFood;}}将工厂本身也做了个抽象,创建ICatFoodFactory接口

publicinterfaceICatFoodFactory{CatFoodcreate(Stringflavor);}各分公司的工厂代码

/***山东分公司简单工厂**@author蝉沐风*/publicclassShanDongSimpleCatFoodFactoryimplementsICatFoodFactory{CatFoodcatFood;@OverridepublicCatFoodcreate(Stringflavor){if("congxiang".equals(flavor)){catFood=newCongXiangCatFood();}elseif("dajiang".equals(flavor)){catFood=newDaJiangCatFood();}else{thrownewRuntimeException("找不到该口味的猫粮");}returncatFood;}}/***湖南分公司简单工厂**@author蝉沐风*/publicclassHuNanSimpleCatFoodFactoryimplementsICatFoodFactory{CatFoodcatFood;@OverridepublicCatFoodcreate(Stringflavor){if("duojiao".equals(flavor)){catFood=newDuoJiaoCatFood();}elseif("mala".equals(flavor)){catFood=newMaLaCatFood();}else{thrownewRuntimeException("找不到该口味的猫粮");}returncatFood;}}各种口味的猫粮代码如下

/***大酱猫粮*/publicclassDaJiangCatFoodextendsCatFood{publicDaJiangCatFood(){this.flavor="dajiang";}@Overridepublicvoidmake(){System.out.println("正在制作【大酱】口味猫粮");}}/***葱香猫粮*/publicclassCongXiangCatFoodextendsCatFood{publicCongXiangCatFood(){this.flavor="congxiang";}@Overridepublicvoidmake(){System.out.println("正在制作【葱香】口味猫粮");}}/***剁椒猫粮*/publicclassDuoJiaoCatFoodextendsCatFood{publicDuoJiaoCatFood(){this.flavor="duojiao";}@Overridepublicvoidmake(){System.out.println("正在制作【剁椒】口味猫粮");}}/***麻辣猫粮*/publicclassMaLaCatFoodextendsCatFood{publicMaLaCatFood(){this.flavor="mala";}@Overridepublicvoidmake(){System.out.println("正在制作【麻辣】口味猫粮");}}产品类对应的UML图为

顾客下单「湖南分公司」的「剁椒猫粮」的代码就变成了这样

publicstaticvoidmain(String[]args){HuNanSimpleCatFoodFactoryhuNanSimpleCatFoodFactory=newHuNanSimpleCatFoodFactory();PaoMaChangV3paoMaChang=newPaoMaChangV3(huNanSimpleCatFoodFactory);//下单剁椒猫粮paoMaChang.order("duojiao");}到此,招财重构完了代码,经过细心检查系统终于上线了,各地分公司使用这套系统有条不紊地开展起自己的业务,形势一片大好!

/***湖南跑码场分公司*@author蝉沐风*/publicclassHuNanPaoMaChangV3{privateICatFoodFactoryfactory;publicHuNanPaoMaChangV3(ICatFoodFactoryfactory){this.factory=factory;}publicCatFoodorder(Stringflavor){CatFoodcatFood=factory.create(flavor);catFood.make();//湖南分公司自己添加了一个「包装」逻辑catFood.pack();returncatFood;}}招财看到,湖南分公司的技术人员在order()方法中擅自添加了一个pack()打包的方法,陀螺继续说道:“先不管这个逻辑加的对不对,光是分公司能够改动我们的核心代码这一点就是有风险的,你需要想个办法,既能让每个分公司自由创建产品,又能保证我们的核心功能不被改变,核心逻辑只能由我们来定。”

“确实是个问题,目前各个分公司的下单逻辑都是自己定义的,我们需要提供一个真正的“框架”,让他们按照我们的标准来进行业务逻辑。”

“没错!”,陀螺欣慰地看着招财。

“既然如此,我可以把我们的PaoMaChangV3改成抽象的,命名为PaoMaChangV4吧,让各个子公司继承这个类,然后为order()添加final关键字,禁止子类进行覆写,这样他们便只能用我们的下单逻辑了”,招财一遍思考一边说。

“那你打算怎么让子公司能自由控制各种产品呢?”,陀螺问道。

招财不慌不忙地回答:“我最近又研究了一下多态和继承,order()方法中的create()方法不做具体操作,将该方法延迟到子类中进行执行。”说罢,招财立刻写了如下代码。

/***跑码场对象-版本4*@author蝉沐风*/publicabstractclassPaoMaChangV4{publicfinalCatFoodorder(Stringflavor){CatFoodcatFood=create(flavor);catFood.make();returncatFood;}//该方法需要子类继承publicabstractCatFoodcreate(Stringflavor);}"order()方法只是调用了create()方法而已,是由子公司创建的子类负责具体实现create()方法,湖南分公司和山东分公司对应的代码如下",招财接着解释道。

/***湖南跑码场分公司V4**@author蝉沐风*/publicclassHuNanPaoMaChangV4extendsPaoMaChangV4{@OverridepublicCatFoodcreate(Stringflavor){CatFoodcatFood;if("duojiao".equals(flavor)){catFood=newDuoJiaoCatFood();}elseif("mala".equals(flavor)){catFood=newMaLaCatFood();}else{thrownewRuntimeException("找不到该口味的猫粮");}returncatFood;}}/***山东跑码场分公司V4**@author蝉沐风*/publicclassShanDongPaoMaChangV4extendsPaoMaChangV4{@OverridepublicCatFoodcreate(Stringflavor){CatFoodcatFood;if("congxiang".equals(flavor)){catFood=newCongXiangCatFood();}elseif("dajiang".equals(flavor)){catFood=newDaJiangCatFood();}else{thrownewRuntimeException("找不到该口味的猫粮");}returncatFood;}}对应的UML图为

最终顾客的下单方式变成了

//下单剁椒猫粮publicstaticvoidmain(String[]args){//顾客首先需要一个湖南分公司的对象PaoMaChangV4huNanPaoMaChangV4=newHuNanPaoMaChangV4();//然后下单huNanPaoMaChangV4.order("duojiao");}“看来真是要对你刮目相看了,你刚刚总结出来的这种思想其实就是大名鼎鼎的工厂方法模式”,陀螺满意地笑了,“工厂方法模式通过让子类决定该创建的对象是什么,来达到将对象创建的过程封装的目的。”

工厂方法模式:定义一个创建对象的接口,担忧子类决定要实例化的类是哪一个,将类的实例化推迟到了子类。

“啊!”,招财大惊,没想到自己误打误撞研究出了工厂方法模式,“我其实并没有想这么多,只是单纯想解决当下的问题,适应未来的变化而已。”

“我知道,恐怕现在让你总结什么时候该用简单工厂模式,什么时候该用工厂方法模式你也未必说的准确。设计模式也不过是前人不断优化自己的代码总结出来的方法论。不必拘泥于你的优化方式叫什么名字,或者干脆忘掉我刚才说的术语吧,在合适的时机运用合适的方法来解决问题才是最重要的!不要学习了设计模式,就觉得自己手上握着锤子,然后看什么都是钉子。”

“我明白了师傅!但是我听说还有一种关于工厂的设计模式,你要不顺便给我讲讲吧。”

“还有一种叫抽象工厂模式,如果你明白了我们系统的一步步优化,这个模式对你来说就太简单了。还是用我们公司的场景给你举例子吧。”

“假如我们想进一步控制分公司生产猫粮的原料,避免每个分公司的原料质量参差不齐。制作猫粮的主要原料都是一样的,都需要肉、燕麦、果蔬、牛磺酸等,但是不同的分公司又有不同的原料生产工艺,抽象工厂就适合于这种场景。”

“那该怎么进行设计呢?”

“这个简单啊,我们可以为每一个分公司创建一个原料工厂,这个原料工厂必须符合我们制定的标准,像这样”,招财写下了伪代码。

publicinterfaceCatFoodIngredientAbstractFactory{//肉类生产MeatcreateMeat();//燕麦生产OatscreateOats();//果蔬生产FruitsAndVegetablescreateFruitsAndVegetables();//牛磺酸生产TaurinecreateTaurine();}"各分公司自己的原料厂必须实现CatFoodIngredientFactory来实现每一个创造方法,以山东分公司为例。"

/***山东分公司猫粮原料厂**@author蝉沐风*/publicclassShanDongCatFoodIngredientFactoryimplementsCatFoodIngredientAbstractFactory{@OverridepublicMeatcreateMeat(){returnnewShanDongMeat();}@OverridepublicOatscreateOats(){returnnewShanDongOats();}@OverridepublicFruitsAndVegetablescreateFruitsAndVegetables(){returnnewShanDongFruitsAndVegetables();}@OverridepublicTaurinecreateTaurine(){returnnewShanDongTaurine();}}注:代码中有很多类未给出实现,大家只需理解其中的含义即可

招财继续问道:“现在怎么把各个分公司的原料工厂和猫粮联系起来呢?”

“别急,为了更好的解释抽象工厂,我们需要先改变一下我们的CatFood类。这里只是为了单纯讲解抽象工厂模式而进行的更改,和我们自身的业务逻辑已经没有关系了。”

/***猫粮的抽象类,所有具体口味的猫粮必须继承自该接口**@author蝉沐风*/publicabstractclassCatFoodV2{publicStringflavor;publicMeatmeat;publicOatsoats;publicFruitsAndVegetablesfruitsAndVegetables;publicTaurinetaurine;publicabstractvoidmake();}“接下来的重点就是如何创建具体口味的猫粮了。你觉得怎么让猫粮和原料厂关联起来呢?”

“可以在子类中添加一个原料工厂的对象,猫粮产品对象的时候可以选择某个原料厂进行初始化,这样就实现了猫粮和具体原料之间的解耦,猫粮类只需要知道怎么制作就可以了,比如像这个样子。”

/***大酱猫粮*/publicclassDaJiangCatFoodV2extendsCatFoodV2{privateCatFoodIngredientFactorycatFoodIngredientFactory;publicDaJiangCatFoodV2(CatFoodIngredientFactorycatFoodIngredientFactory){this.flavor="dajiang";this.catFoodIngredientFactory=catFoodIngredientFactory;}@Overridepublicvoidmake(){System.out.println("正在使用原料:");System.out.println("肉:"+catFoodIngredientFactory.createMeat());System.out.println("燕麦:"+catFoodIngredientFactory.createOats());System.out.println("果蔬:"+catFoodIngredientFactory.createFruitsAndVegetables());System.out.println("牛磺酸:"+catFoodIngredientFactory.createTaurine());System.out.println("制作【大酱】口味猫粮");}}“孺子可教”,陀螺欣慰地说道,“你已经掌握的面向对象的精髓了,那么分公司的代码你也可以写出来了,试试看吧。”

招财很快写出了代码。

/***跑码场对象-版本5**@author蝉沐风*/publicabstractclassPaoMaChangV5{publicfinalCatFoodV2order(Stringflavor){CatFoodV2catFood=create(flavor);catFood.make();returncatFood;}//该方法需要子类继承publicabstractCatFoodV2create(Stringflavor);}/***山东跑码场分公司V5**@author蝉沐风*/publicclassShanDongPaoMaChangV5extendsPaoMaChangV5{//山东分公司采用山东原料厂的原料CatFoodIngredientFactorycatFoodIngredientFactory=newShanDongCatFoodIngredientFactory();@OverridepublicCatFoodV2create(Stringflavor){CatFoodV2catFood;if("congxiang".equals(flavor)){catFood=newCongXiangCatFoodV2(catFoodIngredientFactory);}elseif("dajiang".equals(flavor)){catFood=newDaJiangCatFoodV2(catFoodIngredientFactory);}else{thrownewRuntimeException("找不到该口味的猫粮");}returncatFood;}}“到此为止,我们就用抽象工厂模式完成了业务的改造,顾客下单的逻辑并没有发生变化。为了完整性,我们给出抽象工厂的定义”,陀螺说道。

招财郁闷地说:“你让我自己写我觉得自己能写出来,你解释这么多,我反而头大了!”

“哈哈哈哈哈哈,学习有三种境界,第一种:看山是山,看水是水;第二种:看山不是山,看水不是水;第三种:看山依然山,看水依然水。你现在就处于第一种向第二种过度的阶段”,陀螺打趣道。

“我们从头捋一遍我们系统升级的过程,帮助你理解。”

“刚开始我们公司只生产一种产品——鱼香猫粮,这时你直接针对该产品创建类FishCatFood进行业务逻辑编写即可,不需要进行任何优化。”

“后来公司相继在其他省份创建了子公司,每个子公司都有自己的产品,为了避免SimpleCatFoodFactory成为万能工厂,我们为每个分公司创建了独立的简单工厂,按照我们的要求来创建产品对象。”

“我们并不想让子公司能够修改order()的中的逻辑,因此我们试图创建一个‘框架’,强制让子公司使用我们的下单逻辑,同时又保证子公司自由创建产品的灵活性。于是我们在PaoMaChangV4抽象类中使用了抽象的create()方法,我们将实现create()的行为延迟到子类中,父类中制定了基本框架。这一步使得order()不依赖于具体类,换句话说,这就是解耦。当order()方法调用create()方法是,PaoMaChangV4的子类(子公司对象)将负责创建真正的产品。这就是工厂方法模式。”

“最后我们想确保对每个子公司每个产品原料的控制,定义了原料族。这里有一个隐含的假设,每个产品所使用的原料都是相同的,区别是生产方式不同。”

“我们创建了原料工厂CatFoodIngredientAbstractFactory接口,该接口定义了创建所有原料的接口,再看一下代码。”

publicinterfaceCatFoodIngredientAbstractFactory{//肉类生产MeatcreateMeat();//燕麦生产OatscreateOats();//果蔬生产FruitsAndVegetablescreateFruitsAndVegetables();//牛磺酸生产TaurinecreateTaurine();}"接下来我们为每个分公司创建了实现了CatFoodIngredientAbstractFactory接口的子类来实现每一个创建方法。为了更恰当地解释抽象工厂模式,我们又稍微改造了一下猫粮类,得到了CatFoodV2,所有的具体产品依然继承自CatFoodV2,不同的每个产品都需要从构造器中得到一个原料工厂,注入到对象中的catFoodIngredientFactory变量,CatFoodV2中的make()方法会使用到该工厂创建的原料。"

“最后总结一下抽象工厂模式的使用场景,当你需要使用原料家族来创建想要制造的产品的时候,你就可以考虑使用抽象工厂模式了。”

THE END
1.自制鸡肉猫粮怎样自制猫粮自己做的猫咪的事物一周最好食用一到两次!一岁以下的幼猫一定要以干猫粮为主食,以保证猫咪牙齿的健康。 1、鸡肉: 原料:鸡小胸3两、鸡蛋2个、13香、鸡精、盐微量。 做法:鸡肉剁碎成泥,加鸡蛋、调味品,浅盘上屉蒸熟。 2、鸡肉及肝: 原料:鸡小胸3两、鸡肝2块、鸡蛋1个、调味品不变; http://m.boqii.com/article/61424.html
2.狗粮的成分有哪些制作方法挑选标准摘要:在养狗的日常生活中,选狗粮是很让人比较头疼的一件事情。养狗狗的你,不仅要学会怎么给狗狗选择合适的狗粮,知道狗粮有哪些成分配料、挑选标准是什么,还要学会如何自制狗粮,了解狗粮的制作方法和注意事项,现在的狗主子也不是那么容易当的,下面就一起来了解一下狗粮的相关知识吧。 https://www.cnpp.cn/focus/25305.html
3.国产猫粮制作工艺的提升:为宠物提供更优质的食品一方面,选择新鲜、无污染的肉类原料,确保蛋白质的质量和营养价值;另一方面,注重谷物、蔬菜等辅助原料的品质,以提供猫咪所需的碳水化合物、纤维和维生素。通过严格筛选原料为提升产品质量奠定基础。 二、科学的配方研发 在猫粮制作过程中,配方的研发至关重要。信元发育宝的研发团队汇集了药师、兽医师、营养师、微生物学家https://www.iyiou.com/news/202312211057971
4.并[3,4导航: X技术> 最新专利>医药医疗技术的改进;医疗器械制造及应用技术专利名称:吡唑并[3,4-b]吡啶化合物及其作为磷酸二酯酶抑制剂的用途的制作方法 技术领域:本发明涉及吡唑并吡啶化合物、它们的制备方法、在制备方法中使用的中间体、以及包含所述化合物的药物组合物。本发明还涉及所述吡唑并吡啶化合物的治疗用途,http://xjishu.com/zhuanli/05/200380109835.html
5.欧洲高端进口猫粮测评:Wildcat绿袋子的配方封神了!为了满足不同铲屎官的需求,除了测评一些比较平价的国产猫粮之外,我们也要看看一些高端的进口猫粮。毕竟在宠物食品领域,国产粮不论是在发展历史、营养研究、制作工艺还是品控等方面,和进口粮还是有些差距的。 今天,我们要给大家测评一款德国Wildcat(野猫)鸡肉粮,预算充足,想让猫咪长肉的铲屎官可以来看看哦~ https://www.isdpp.com/xq-14946.html
6.猫粮销售排行(10款猫粮排行榜,性价比高,放心冲!)这款进口猫粮符合中欧美三国标准,价格实惠,性价比极高,价格:297元/斤营养:粗脂肪≥15%,粗蛋白质≥43%主要原料:鲜鸡肉、鸡肉粉妙修猫粮精选优质鸡肉来源,含高达83%动物原料来源,无谷配方,单一肉源,更好消化。 ?10款猫粮排行榜,性价比高,放心冲! https://www.niaogebiji.com/article-560463-1.html
7.如果只选择国产,请问猫粮哪个品牌好?一款品质靠谱的猫粮简单概括有以下7点: 1、原料组成定义清晰且占比明确,肉类原料不能出现禽类、鱼类,肉类及制品等模糊定义; 2、猫咪属于肉食动物,蛋白含量至少>30%,高端猫粮需>40%; 3、牛磺酸对猫咪至关重要,但其无法自身合成,猫粮制作中需进行添加,一般为0.2%; https://www.yoojia.com/ask/17-11173920616636819964.html
8.乖宝宠物2023年年度董事会经营评述基于多年服务国际客户所积累的产品研发优势、生产工艺优势、质量管控优势和对行业发展的深刻理解,公司旗下自主品牌“麦富迪”以其过硬的产品质量获得了国内消费者的高度认可,市场占有率在国内同行业中名列前茅,在多个电商平台销量稳居第一;高端猫粮品牌“弗列加特”也取得高速增长,短短几年已成长为国内高端猫粮头部品牌。http://yuanchuang.10jqka.com.cn/20240415/c656884480.shtml