设计模式-工厂方法模式(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)
在开发系统中,经常会碰到一个问题.现在需要实现的一些功能,但是这个功能模块以后一定是需要扩展的,那么现在开发中就不仅要实现现在的功能,还要考虑以后的扩展.那么为了系统的健壮,扩展就要遵循开闭原则(简单 ...
随机推荐
- FBI传授9秘诀:如何看穿对方在撒谎 z
第1招:不提及自身和姓名 美国赫特福德郡大学的心理学家韦斯曼说,〝人们在说谎时会本能地把自己从他们所说的谎言中剔除出去〞.所以如果你向某人提问时,他们总是反覆地省略〝我〞,他们就有被怀疑的理由了.反过 ...
- "undefined reference to" 问题解决方法 -链接问题
最近在Linux下编程发现一个诡异的现象,就是在链接一个静态库的时候总是报错,类似下面这样的错误: (.text+0x13): undefined reference to `func' 关于unde ...
- CRM SQL 共享
共四步 ,) PRIMARY KEY CLUSTERED, objectid UNIQUEIDENTIFIER NOT NULL, objecttype INT NOT NULL) ,,'883D4 ...
- crm 4 隐藏自定义 toolbar
//隐藏指定title按钮 function hideISVButton(buttonTitle) { var comps = document.getElementsByTagName('li'); ...
- 你可能不知道的 30 个 Python 语言的特点技巧
列表按难度排序,常用的语言特征和技巧放在前面. 1.1 分拆 >>> a, b, c = 1, 2, 3>>> a, b, c(1, 2, 3)> ...
- mysql触发器查看
查询触发器列表 SHOW TRIGGERS; 但是这个无法查询到没有权限的触发器,可以试试这个 select * from sym_trigger where source_table_name li ...
- 读写ZIP文件
String zipFile = /D:/+ ".zip"; StringOperator.zip(filePath, zipFile); InputStream is = ...
- OS X 升级 Yosemite 后,Intellij IDEA 与 VirtualBox 启动失败
报错: Dyld Error Message: Symbol not found: _CGContextSetAllowsAcceleration Referenced from: /Library/ ...
- jdk线程常见面试题
请编写一个多线程程序,实现两个线程,其中一个线程完成对某个对象int成员变量的增加操作,即每次加1,另一个线程完成对该对象成员变量的减操作,即每次减1,同时要保证该变量的值不会小于0,不会大于1,该变 ...
- css列表
列表是有三种形式: 1.无序列表,用来表示一个列表语义,并且每个项目与项目之间是不分先后顺序的 ul 的英文unordered list "无序列表" li 的英文 list ...