设计模式-工厂方法模式(FactoryMethod)
简介:
简单工厂模式将类的示例化放在工厂对象中。
工厂方法模式是简单工厂模式的延伸,不同的是其将子类的实例化延迟到子类工厂中实现,本身仅定义一个创建对象的接口。
工厂方法模式主要由四部分组成:
1.抽象产品(product) -同简单工厂模式
是所有具体产品角色的父类,它负责描述所有实例所共有的公共接口,抽象类或者接口
2.具体产品(Concrete Product) -同简单工厂模式
即为Product的实现对象,特指某一具体产品,一般有多个这样的类。3.工厂角色(Creator) -同简单工厂模式
工厂基类,可以为接口、抽象类、实体类,声明工厂方法,工厂方法一般为抽象方法,返回Product对象,也可以在工厂方法中提供默认实现,返回一个Default的Product实例对象。
4.具体工厂角色(ConcreteCreator)
重写Creator中的工厂方法,返回具体的Product实例。
具体实例:
上面简单工厂的例子,已经很好的实现了对交易修改备案的操作。不管后续新增任何交易,稍微改下代码即可轻松实现修改备案记录。
现在客户提到,要对系统中账户修改、对手修改记录修改备案,PS:以后可能还会有其他对象的修改备案。
代码实现:
public abstract class DiffClass
{
public abstract void Diff(Object aOldObject, Object aNewObject);
} public class AccountDiff : DiffClass
{
public override void Diff(Object aOldAccount, Object aNewAccount)
{
Console.WriteLine("记录账户修改备案信息");
}
} public class PartyDiff : DiffClass
{
public override void Diff(Object aOldParty, Object aNewParty)
{
Console.WriteLine("记录交易对手修改备案信息");
}
} interface IFactoryMethod
{
DiffClass CreateDiffClass();
} public class AccountFactory : IFactoryMethod
{
public DiffClass CreateDiffClass()
{
return new AccountDiff();
}
} public class PartyFactory : IFactoryMethod
{
public DiffClass CreateDiffClass()
{
return new PartyDiff();
}
} class FactoryMethodTest
{
static void Main(String[] args)
{
Account oldAccount = new Account();
Account newAccount = new Account();
IFactoryMethod factory1 = new AccountFactory();
factory1.CreateDiffClass().Diff(oldAccount, newAccount); Party oldParty = new Party();
Party newParty = new Party();
IFactoryMethod factory2 = new PartyFactory();
factory2.CreateDiffClass().Diff(oldParty, newParty);Console.ReadLine();
}
}
后续如果用户提到需要记录用户修改备案,不用修改原始代码,新增代码如下即可:
public class UserDIff : DiffClass
{
public override void Diff(object aOldUser, object aNewUser)
{
Console.WriteLine("记录用户修改备案信息");
}
} public class UserFactory : IFactoryMethod
{
public DiffClass CreateDiffClass()
{
return new UserDIff();
}
}
补充分析:
工厂方法模式的本质:延迟到子类来选择实现
优点:
a.工厂方法给子类提供了一个挂钩,使得扩展新的对象更容易。例如上面提到的新增用户修改备案或者后续新增其它对象的修改备案,不需要修改原有任何代码。新增新的工厂方法和新的子类即可。
b.可以在不知道具体实现的情况下编程
父类的工厂模式本身一般不实例化具体产品对象,不关心细节,创建具体产品对象的任务延迟到子类中。
缺点:
工厂方法中需要创建产品对象,也就是需要选择具体的产品对象并创建他们的实例,具体产品对象和工厂方法耦合。
跟简单工厂模式的区别:
简单工厂模式,直接在工厂类中选择实现具体产品实例。
工厂方法模式,将具体产品的实例放在具体工厂里(工厂角色的子类)。父类工厂角色里面的工厂方法,依赖于抽象而不是具体实现,面向接口编程。
其它代码:
简单工厂模式本身是工厂方法模式的一种特殊情况。其实显示中两种模式是可以混和使用的。
参考代码如:
#region 简单工厂
public abstract class DiffClass
{
public abstract void Diff(Object aOldObject, Object aNewObject);
} public class BondTradeDiff : DiffClass
{
public override void Diff(Object aOldTrade, Object aNewTrade)
{
Console.WriteLine("记录现券交易备案!");
}
} public class FutureTradeDiff : DiffClass
{
public override void Diff(Object aOldTrade, Object aNewTrade)
{
Console.WriteLine("记录期货交易备案");
}
} public class FactoryMethod
{
public virtual DiffClass CreateDiffClass(object aObject)//参数化工厂方法
{
if (aObject is BondTrade)
return new BondTradeDiff();
else if (aObject is FutureTrade)
return new FutureTradeDiff();
else
return null;
}
}
#endregion #region 工厂方法
public class AccountDiff : DiffClass
{
public override void Diff(Object aOldAccount, Object aNewAccount)
{
Console.WriteLine("记录账户修改备案信息");
}
} public class AccountFactory : FactoryMethod
{
public override DiffClass CreateDiffClass(object aObject)
{
return new AccountDiff();
}
}
#endregion #region 测试代码
public class SimpleFactoryAndFactoryMethod
{
static void Main(String[] args)
{
FactoryMethod factory = new FactoryMethod(); //测试现券交易修改备案
Trade oldBondTrade = new BondTrade();
Trade newBondTrade = new BondTrade();
factory.CreateDiffClass(newBondTrade).Diff(oldBondTrade, newBondTrade); //测试期货交易修改备案
Trade oldFutureTrade = new FutureTrade();
Trade newFutureTrade = new FutureTrade();
factory.CreateDiffClass(newFutureTrade).Diff(oldFutureTrade, newFutureTrade); //测试账户修改备案
Account oldAccount = new Account();
Account newAccount = new Account();
FactoryMethod factory1 = new AccountFactory();
factory1.CreateDiffClass(newAccount).Diff(oldAccount, newAccount); Console.ReadLine();
}
}
#endregion
}
设计模式-工厂方法模式(FactoryMethod)的更多相关文章
- Java设计模式---工厂方法模式(Factory-Method)
一.普通工厂模式 建立一个工厂类,对实现了同一接口的一些类进行实例的创建 实例代码: 发送短信和邮件的例子,首先创建接口: public interface Sender { public void ...
- 4. 星际争霸之php设计模式--工厂方法模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- C++设计模式——工厂方法模式
本文版权归果冻说所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利.» 本文链接:http://www.jellythink.com/arch ...
- Python设计模式——工厂方法模式(FactoryMethod)
需求:有一个学雷锋活动,有买米和扫地两个内容,参与的人有大学生和社区志愿者,他们各自的方法不一样. 如果用简单工厂模式实现: #encoding=utf-8 __author__ = 'kevinlu ...
- Java 设计模式(四)-工厂方法模式 (FactoryMethod Pattern)
1 概念定义 1.1 定义 定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 1.2 类型 创建类模式 2 原理特征 2.1 类 ...
- 设计模式-工厂方法模式(FactoryMethod)
工厂方法模式又称多态工厂模式.工厂方法模式是定义一个创建产品对象的接口(FruitFactory),将具体创建工作给具体的实现类(AppFactory,BananaFactory,PearFactor ...
- JAVA设计模式--工厂方法模式
工厂方法设计模式 抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关.是具体工厂角色必须实现的接口或者必须继承的父类.在java中它由抽象类或者接口来实现.具体工厂角色:它含有和具体业务逻辑有关 ...
- 深入浅出设计模式——工厂方法模式(Factory Method)
介绍在简单工厂模式中,我们提到,工厂方法模式是简单工厂模式的一个延伸,它属于Gof23中设计模式的创建型设计模式.它解决的仍然是软件设计中与创建对象有关的问题.它可以更好的处理客户的需求变化. 引入我 ...
- 设计模式 — 工厂方法模式(Factory Method)
在开发系统中,经常会碰到一个问题.现在需要实现的一些功能,但是这个功能模块以后一定是需要扩展的,那么现在开发中就不仅要实现现在的功能,还要考虑以后的扩展.那么为了系统的健壮,扩展就要遵循开闭原则(简单 ...
随机推荐
- Apache Thrift学习之二(基础及原理)
Apache Thrift 是 Facebook 实现的一种高效的.支持多种编程语言的远程服务调用的框架.本文将从 Java 开发人员角度详细介绍 Apache Thrift 的架构.开发和部署,并且 ...
- .nil? .empty? .blank? .present? in Ruby on Rails
We get confused when there are many options to choose from. Same is the case when it comes to use an ...
- grep和sed替换文件中的字符串
sed -i s/"str1"/"str2"/g `grep "str1" -rl --include="*.[ch]" ...
- JVM加载class文件的原理机制
Java中的所有类,都需要由类加载器装载到JVM中才能运行.类加载器本身也是一个类,而它的工作就是把class文件从硬盘读取到内存中.在写程序的时候,我们几乎不需要关心类的加载,因为这些都是隐式装载的 ...
- http://host:8399/arcgis/rest/services/ 访问不了
一.问题: 安装完arvserver后,rest服务http://host:8399/arcgis/rest/services/访问不了 二.问题原因: 查看了一下manager日志,其中记录了几个r ...
- div 滚动定位代码
var thisheith; $(function () { var divid = '#14681-121320-197209'; $(di ...
- HDU 4405 【概率dp】
题意: 飞行棋,从0出发要求到n或者大于n的步数的期望.每一步可以投一下筛子,前进相应的步数,筛子是常见的6面筛子. 但是有些地方可以从a飞到大于a的b,并且保证每个a只能对应一个b,而且可以连续飞, ...
- java常用面板
public class JPanelTest extends JFrame{ public JPanelTest(){ Container c=getContentPane(); ...
- Python第九章模块和包
1.import Python文件的时候文件名不能跟Python中自带的关键字重复,否则无法使用关键字的方法. 2.Reload(),重载例子 import sysreload(sys)sys.set ...
- ELK+redis集群搭建
ELK版本: logstash-1.4.2 kibana-4.0.3 redis-3.0.0 elasticsearch-1.4.4(最低版本) 分别启动命令: redis-server redis. ...