读书笔记6:工厂方法模式
2015-07-30 12:52
369 查看
1、概念
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法是一个类的实例化延伸到子类。
2、背景
已经知道工厂模式,有一个父类SuperClass,以及这个父类的不同实现方法和算法的若干个子类ClassA,ClassB... ...,有一个工厂类DAOFactory,根据客户端传来的标识决定调用哪个子类。如下:
[csharp] view
plaincopyprint?
using System;
using System.Collections.Generic;
using System.Text;
namespace FactoryPattern
{
public abstract class SuperClass
{
public abstract void GetResult();
}
public class ClassA:SuperClass
{
public override void GetResult()
{
Console.WriteLine("A类对GetResult()的实现。");
}
}
public class ClassB : SuperClass
{
public override void GetResult()
{
Console.WriteLine("B类对GetResult()的实现。");
}
}
public class DAOFactory
{
static SuperClass super;
public static SuperClass CreateSuperClass(string type)
{
switch (type)
{
case "A":
super = new ClassA();
break;
case "B":
super = new ClassB();
break;
default:
break;
}
return super;
}
}
}
客户端
[csharp] view
plaincopyprint?
using System;
using System.Collections.Generic;
using System.Text;
namespace FactoryPattern
{
class Program
{
static void Main(string[] args)
{
SuperClass sup;
sup = DAOFactory.CreateSuperClass("A");
sup.GetResult();
sup = DAOFactory.CreateSuperClass("B");
sup.GetResult();
Console.ReadLine();
}
}
}
结果
可以看出,简单工厂模式是把到底实例化哪个类的逻辑放在工厂里判断,客户端不需要知道调用的哪个类,只关心结果就可以了。但是这里有一个问题,如果需求有了变化。那么就要增加新的类ClassC,ClassD… … 增加类不影响程序是可行的,但工厂类中的switch分支要不断地加,也就是要不断修改DAOFactory类,不符合开放封闭原则(程序实体可以扩展,但不被修改)。那么如何解决?
3、工厂方法模式
根据问题,可以有这样的方案,类ClassC,ClassD照常增加,但是需要修改工厂类。
[csharp] view
plaincopyprint?
using System;
using System.Collections.Generic;
using System.Text;
namespace FactoryPattern
{
public abstract class SuperClass
{
public abstract void GetResult();
}
public class ClassA:SuperClass
{
public override void GetResult()
{
Console.WriteLine("A类对GetResult()的实现。");
}
}
public class ClassB : SuperClass
{
public override void GetResult()
{
Console.WriteLine("B类对GetResult()的实现。");
}
}
public class ClassC : SuperClass
{
public override void GetResult()
{
Console.WriteLine("C类对GetResult()的实现。");
}
}
public class ClassD : SuperClass
{
public override void GetResult()
{
Console.WriteLine("D类对GetResult()的实现。");
}
}
public interface IFactory
{
SuperClass CreateSuperClass();
}
public class AFactory : IFactory
{
public SuperClass CreateSuperClass()
{
return new ClassA();
}
}
public class BFactory : IFactory
{
public SuperClass CreateSuperClass()
{
return new ClassB();
}
}
public class CFactory : IFactory
{
public SuperClass CreateSuperClass()
{
return new ClassC();
}
}
public class DFactory : IFactory
{
public SuperClass CreateSuperClass()
{
return new ClassD();
}
}
}
客户端
[csharp] view
plaincopyprint?
using System;
using System.Collections.Generic;
using System.Text;
namespace FactoryPattern
{
class Program
{
static void Main(string[] args)
{
IFactory factory;
SuperClass sup;
factory = new CFactory();
sup = factory.CreateSuperClass();
sup.GetResult();
factory = new DFactory();
sup = factory.CreateSuperClass();
sup.GetResult();
Console.ReadLine();
}
}
}
结果
这样,解决了修改分支的问题。但是把选择交给了客户端,需要客户端自己判断到底需要调用哪个类实现,如果需求变化客户端就需要修改。事物都是具有两面性的,因此到底使用哪种模式还需要在程序中视情况而定。
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法是一个类的实例化延伸到子类。
2、背景
已经知道工厂模式,有一个父类SuperClass,以及这个父类的不同实现方法和算法的若干个子类ClassA,ClassB... ...,有一个工厂类DAOFactory,根据客户端传来的标识决定调用哪个子类。如下:
[csharp] view
plaincopyprint?
using System;
using System.Collections.Generic;
using System.Text;
namespace FactoryPattern
{
public abstract class SuperClass
{
public abstract void GetResult();
}
public class ClassA:SuperClass
{
public override void GetResult()
{
Console.WriteLine("A类对GetResult()的实现。");
}
}
public class ClassB : SuperClass
{
public override void GetResult()
{
Console.WriteLine("B类对GetResult()的实现。");
}
}
public class DAOFactory
{
static SuperClass super;
public static SuperClass CreateSuperClass(string type)
{
switch (type)
{
case "A":
super = new ClassA();
break;
case "B":
super = new ClassB();
break;
default:
break;
}
return super;
}
}
}
客户端
[csharp] view
plaincopyprint?
using System;
using System.Collections.Generic;
using System.Text;
namespace FactoryPattern
{
class Program
{
static void Main(string[] args)
{
SuperClass sup;
sup = DAOFactory.CreateSuperClass("A");
sup.GetResult();
sup = DAOFactory.CreateSuperClass("B");
sup.GetResult();
Console.ReadLine();
}
}
}
结果
可以看出,简单工厂模式是把到底实例化哪个类的逻辑放在工厂里判断,客户端不需要知道调用的哪个类,只关心结果就可以了。但是这里有一个问题,如果需求有了变化。那么就要增加新的类ClassC,ClassD… … 增加类不影响程序是可行的,但工厂类中的switch分支要不断地加,也就是要不断修改DAOFactory类,不符合开放封闭原则(程序实体可以扩展,但不被修改)。那么如何解决?
3、工厂方法模式
根据问题,可以有这样的方案,类ClassC,ClassD照常增加,但是需要修改工厂类。
[csharp] view
plaincopyprint?
using System;
using System.Collections.Generic;
using System.Text;
namespace FactoryPattern
{
public abstract class SuperClass
{
public abstract void GetResult();
}
public class ClassA:SuperClass
{
public override void GetResult()
{
Console.WriteLine("A类对GetResult()的实现。");
}
}
public class ClassB : SuperClass
{
public override void GetResult()
{
Console.WriteLine("B类对GetResult()的实现。");
}
}
public class ClassC : SuperClass
{
public override void GetResult()
{
Console.WriteLine("C类对GetResult()的实现。");
}
}
public class ClassD : SuperClass
{
public override void GetResult()
{
Console.WriteLine("D类对GetResult()的实现。");
}
}
public interface IFactory
{
SuperClass CreateSuperClass();
}
public class AFactory : IFactory
{
public SuperClass CreateSuperClass()
{
return new ClassA();
}
}
public class BFactory : IFactory
{
public SuperClass CreateSuperClass()
{
return new ClassB();
}
}
public class CFactory : IFactory
{
public SuperClass CreateSuperClass()
{
return new ClassC();
}
}
public class DFactory : IFactory
{
public SuperClass CreateSuperClass()
{
return new ClassD();
}
}
}
客户端
[csharp] view
plaincopyprint?
using System;
using System.Collections.Generic;
using System.Text;
namespace FactoryPattern
{
class Program
{
static void Main(string[] args)
{
IFactory factory;
SuperClass sup;
factory = new CFactory();
sup = factory.CreateSuperClass();
sup.GetResult();
factory = new DFactory();
sup = factory.CreateSuperClass();
sup.GetResult();
Console.ReadLine();
}
}
}
结果
这样,解决了修改分支的问题。但是把选择交给了客户端,需要客户端自己判断到底需要调用哪个类实现,如果需求变化客户端就需要修改。事物都是具有两面性的,因此到底使用哪种模式还需要在程序中视情况而定。
相关文章推荐
- 未测试---- mysql+spring+mybatis实现数据库读写分离[代码配置]
- windows 10 正式版下载与激活
- Qt 5.3 下OpenCV 2.4.11 开发(5)最高效的像素引用
- 读书笔记5:代理模式
- 【HttpClient4.5中文教程】【第一章 :基础】1.1执行请求(二)
- 《了不起的盖茨比》
- sed 用法
- ASCII表
- 详细解析SELECT模型
- Spock Proxy
- 读书笔记4:单例模式
- freemark 页面静态化
- AMF3 在Unity中使用AMF3和Java服务器通信
- thinkphp 构建子查询
- shell 脚本执行错误
- Activity中Window对象的创建过程
- typedef指针连用
- poi 导出功能。
- 关于监听器的使用(服务器启动时加载数据)
- 它们的定义Adapterg在etView( )正在使用View.setTag()与不同的是不使用。