我能想到最浪漫的事,就是和你一起慢慢变胖。

我能想到最浪漫的事,就是和你一起慢慢变胖。

PHP设计模式笔记:使用PHP实现工厂模式
【意图】
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使用一个类的实例化延迟到其子类【GOF95】
【工厂模式结构图】
【工厂模式中主要角色】
抽象产品(Product)角色:具体产品对象共有的父类或接口
具体产品(Concrete Product)角色:实现抽象产品角色所定义的接口,并且工厂方法模式所创建的每一个对象都是某具体产品对象的实例
抽象工厂(Creator)角色:模式中任何创建对象的工厂类都要实现这个接口,它声明了工厂方法,该方法返回一个Product类型的对象。
Creator也可以定义一个工厂方法的缺省实现,它返回一个缺省的的ConcreteProduct对象
具体工厂(Concrete Creator)角色:实现抽象工厂接口,具体工厂角色与应用逻辑相关,由应用程序直接调用以创建产品对象。
【工厂模式的优点和缺点】
工厂模式的优点
工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。
工厂模式的缺点
客户可能仅仅为了创建一个特定的ConcreteProduct对象,就不得不创建一个Creator子类
【工厂模式适用场景】
1、当一个类不知道它所必须创建的对象的类的时候
2、当一个类希望由它的子类来指定它所创建的对象的时候
3、当类将创建对象的职责委托给多个帮助子类的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候
【工厂模式与其它模式】
抽象工厂模式(abstract factory模式):Abstract Factory模式经常使用工厂方法来实现
Template Method模式: 工厂方法通常在Template Methods中被调用
【工厂模式PHP示例】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | <?php /** * 工厂模式 2010-06-25 sz * @author 胖子 phppan.p#gmail.com http://www.phppan.com * 哥学社成员(http://www.blog-brother.com/) * @package design pattern */ /** * 抽象工厂角色 */ interface Creator { public function factoryMethod(); } /** * 具体工厂角色A */ class ConcreteCreatorA implements Creator { /** * 工厂方法 返回具体 产品A * @return ConcreteProductA */ public function factoryMethod() { return new ConcreteProductA(); } } /** * 具体工厂角色B */ class ConcreteCreatorB implements Creator { /** * 工厂方法 返回具体 产品B * @return ConcreteProductB */ public function factoryMethod() { return new ConcreteProductB(); } } /** * 抽象产品角色 */ interface Product { public function operation(); } /** * 具体产品角色A */ class ConcreteProductA implements Product { /** * 接口方法实现 输出特定字符串 */ public function operation() { echo 'ConcreteProductA <br />'; } } /** * 具体产品角色B */ class ConcreteProductB implements Product { /** * 接口方法实现 输出特定字符串 */ public function operation() { echo 'ConcreteProductB <br />'; } } class Client { /** * Main program. */ public static function main() { $creatorA = new ConcreteCreatorA(); $productA = $creatorA->factoryMethod(); $productA->operation(); $creatorB = new ConcreteCreatorB(); $productB = $creatorB->factoryMethod(); $productB->operation(); } } Client::main(); ?> |
【工厂方法模式与简单工厂模式】
工厂方法模式与简单工厂模式再结构上的不同不是很明显。工厂方法类的核心是一个抽象工厂类,而简单工厂模式把核心放在一个具体类上。
工厂方法模式之所以有一个别名叫多态性工厂模式是因为具体工厂类都有共同的接口,或者有共同的抽象父类。
当系统扩展需要添加新的产品对象时,仅仅需要添加一个具体对象以及一个具体工厂对象,原有工厂对象不需要进行任何修改,也不需要修改客户端,很好的符合了”开放-封闭”原则。而简单工厂模式在添加新产品对象后不得不修改工厂方法,扩展性不好。
工厂方法模式退化后可以演变成简单工厂模式。
问题描述
【Description】
卡门——农夫约翰极其珍视的一条Holsteins奶牛——已经落了到“垃圾井”中。“垃圾井”是农夫们扔垃圾的地方,它的深度为D (2 <= D <= 100)英尺。
卡门想把垃圾堆起来,等到堆得与井同样高时,她就能逃出井外了。另外,卡门可以通过吃一些垃圾来维持自己的生命。
每个垃圾都可以用来吃或堆放,并且堆放垃圾不用花费卡门的时间。
假设卡门预先知道了每个垃圾扔下的时间t(0
这道题可以用DP解决。用l[i,j]表示掉下来i个垃圾后,卡门爬上的高度为j时她最长的寿命。显然l[0,0]=10。对于任一个状态l[i-1,j],若l[i-1,j]>=g[i].time,说明这个状态的卡门能够坚持到下一个垃圾下落。在这种情况下,按以下两种方法处理第i个垃圾,即进行状态转移:
吃掉第i个垃圾,即update(l[i,j],l[i-1,j]+g[i].life);
用第i个垃圾来垫高。令t=j+g[i].height,即把第i个垃圾用来垫高后卡门爬上的总高度。如果t>=d,则卡门于g[i].time时爬了出来,否则update(l[i,t],l[i-1,j])。
若首次遇到某一个l[i,0]一次也没有赋值,说明卡门不可能坚持到第i个垃圾下落,则她最多可以存活的时间为l[i-1,0](即把前i-1个垃圾全吃掉后的寿命)。
注意到在计算l数组的第i行时只用到了第i-1行,因此l数组可用滚动数组来实现。
【代码】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | #include <stdio.h> #include <string.h> #define MAXN 101 #define max(a,b) a>b?a:b typedef struct node { int time, life, height; }node; int main() { node a[MAXN], temp; int flag; int f[MAXN][MAXN * 10]; int n, d, i, j, k, t, maxt, m; scanf("%d%d", &d, &n); maxt = 0; for (i = 1; i <= n; i++) { scanf("%d%d%d", &a[i].time, &a[i].life, &a[i].height); } for (i = 1; i < n; i++) { for (j = i + 1; j <= n; j++) { if (a[i].time > a[j].time) { temp = a[i]; a[i] = a[j]; a[j] = temp; } } } memset(f, 0, sizeof(f)); f[0][0] = 10; flag = 0; maxt = 0; for (i = 1; i <= n; i++) { m = 0; k = 0; for (j = 0; j <= maxt; j++) { if (f[i - 1][j] >= a[i].time) { f[i][j] = max(f[i][j], f[i - 1][j] + a[i].life); t = j + a[i].height; if (t >= d) { flag = a[i].time; break; } if (t > m) m = t; f[i][t] = max(f[i][t], f[i - 1][j]); k++; } } if (k == 0) break; if (flag != 0) break; maxt = m; } if (flag != 0) printf("%d\n", flag); else { printf("%d\n", f[i - 1][0]); } return 0; } |
应该是5年前的代码了,从以前的百度blog中转了过来