有朋友看了我这篇文章后说模式并不存在相互转换,因为它们有不同的应用背景,我认为用转换的确不妥,那就改用功能替换吧,就是说一个功能的实现并不局限于一种模式.

在上一篇实际项目中的策略模式应用中,我分析了一下实际项目中如何应用策略模式,我们知道设计模式有二十多种,是不是在一个实现方法上只能唯一使用一种模式呢?它们之间是否有共同点,或者说它们之间是不是可以转换呢?

在这篇文章中我还是继续上一篇的项目来说一下策略模式有没有可能和工厂模式相互转换,知道设计模式的朋友一定知道,工厂模式在设计模式当中的应用应该来说是最多的,因为它是很多模式的基础.

策略模式的类图如下:

工厂方法模式的思想:

      简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。

     该模式中包含的角色及其职责工厂(Creator)角色.

     简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。

     抽象(Product)角色

     简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。

具体产品(Concrete Product)角色

    简单工厂模式的特点:

    简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。

     在这个模式中,工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。有利于整个软件体系结构的优化。

    不难发现,简单工厂模式的缺点也正体现在其工厂类上,由于工厂类集中了所有实例的创建逻辑,所以“高内聚”方面做的并不好。另外,当系统中的具体产品类不断增多时,可能会出现要求工厂类也要做相应的修改,扩展性并不很好。

   本人将上文中导出数据部分转换为用工厂模式的方法实现,类关系图如下:

   此方法中的具体实现方法我就省略了,有兴趣的朋友可能去看下jillzhang的博客,里面有关于组件开发的文章.

    
   接口如下:
     

Code
   /**//// <summary>
    /// 将GridView导出到其他文件的接口
    /// </summary>
    public interface IExporter
    {

        /**//// <summary>
        /// 导出类型的名称
        /// </summary>
        string ExportTypeName { get;set;}

        /**//// <summary>
        /// 将GirdView导出为其他格式的文件
        /// </summary>
        /// <param name="grid">要导出的GridView对象</param>
        /// <param name="unExportedColumnNames">不导出的列名称集合</param>
        void Export(GridView grid);


    }


工厂类如下:
   

Code
public class FactoryDAL 
    {
        /**//// <summary>
        /// create instance by type
        /// </summary>
        /// <param name="sType"></param>
        /// <returns></returns>
        public static IExporter createInstance(string sType) 
        {
            IExporter EX=null ;
            switch (sType)
            {
                case "excel":
                    EX= new ExcelExporter();
                    break;
                case "word":
                    EX = new WordExporter();
                    break;
                case "pdf":
                    EX = new PdfExporter();
                    break;
                default :
                    EX = new ExcelExporter();
                    break;
                
            }
            return EX;
        }
    } 


根据不同的导出类型实现的具体类如下:

Code
/**//// <summary>
    /// Excel导出
    /// </summary>
    public class ExcelExporter:IExporter
    {
        private string _ExportTypeName = "导出方式为EXCEL";
        /**//// <summary>
        /// 导出类型的名称
        /// </summary>
       public  string ExportTypeName 
        {
            get { return this ._ExportTypeName ; }
            set{this._ExportTypeName =value ; }
        }
        public methods#region public methods
        /**//// <summary>
        /// 将GirdView导出为其他格式的文件
        /// </summary>
        /// <param name="grid">要导出的GridView对象</param>
        /// <param name="unExportedColumnNames">不导出的列名称集合</param>
        public void Export(GridView grid)
        {
            //具体代码略

        }
        #endregion

    }
Code
   public class PdfExporter : IExporter
    {
        private string _ExportTypeName = "导出方式为pdf";
        /**//// <summary>
        /// 导出类型的名称
        /// </summary>
        public string ExportTypeName
        {
            get { return this._ExportTypeName; }
            set { this._ExportTypeName = value; }
        }
        public PdfExporter()
        {

        }
        public  void Export(GridView grid)
        {
            //具体代码略
       
        }
    }
Code
/**//// <summary>
    /// Word导出
    /// </summary>
    public  class WordExporter:IExporter
    {
        private string _ExportTypeName = "导出方式为word";
        /**//// <summary>
        /// 导出类型的名称
        /// </summary>
        public string ExportTypeName
        {
            get { return this._ExportTypeName; }
            set { this._ExportTypeName = value; }
        }
        public methods#region public methods
        /**//// <summary>
        /// 将GirdView导出为其他格式的文件
        /// </summary>
        /// <param name="grid">要导出的GridView对象</param>
        /// <param name="unExportedColumnNames">不导出的列名称集合</param>
        public void Export(GridView grid)
        {
            //具体代码略
        }
        #endregion
    }

客户端调用:
  前台页面:
    

Code
 <asp:DropDownList ID="DropDownList1" runat="server">
            <asp:ListItem Selected="True" Value="pdf">pdf导出</asp:ListItem>
            <asp:ListItem Value="word">word导出</asp:ListItem>
            <asp:ListItem Value="excel">excel导出</asp:ListItem>
        </asp:DropDownList>
        <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="导出" />


cs:
   

Code
protected void Button1_Click(object sender, EventArgs e)
        {
            IExporter EX = FactoryDAL.createInstance(this.DropDownList1.SelectedValue.ToString().Trim());
            Response.Write(EX.ExportTypeName);
        }


    我只是想说明下工厂模式和其它模式的关系,也并不是说此种转换一定实用于实际项目,这还是要实际情况实际分析,不同的模式有不同的好处,只要能够解决问题就是好方法,古人云:条条大道通罗马.在模式的应用中我们一般是主张利用组合,少用继承,可以将多种模式结合起来用,这样可以扬长补短.

注:本文参考了下面文章:http://baike.baidu.com/view/1227908.htm

设计模式之间可以相互功能替换吗?相关推荐

  1. java GoF 的 23 种设计模式的分类和功能

    摘抄:http://c.biancheng.net/view/1320.html 1.什么是GoF(摘抄自百度词条) <Design Patterns: Elements of Reusable ...

  2. GoF的23种设计模式的分类和功能

    设计模式有两种分类方法,即根据模式的目的来分和根据模式的作用范围来分. 根据目的来分 根据模式是用来完成什么工作来划分,这种方式可分为创建型模式.结构性模式和行为模式3种. 创建型模式:用于描述&qu ...

  3. 抽象工厂和工厂设计模式之间有什么区别?

    我知道有很多关于这两种模式之间差异的帖子,但有一些我找不到的东西. 从我一直在阅读的内容中,我看到工厂方法模式允许您定义如何创建单个具体产品,但是从客户端隐藏实现,因为他们将看到通用产品. 我的第一个 ...

  4. 构架、框架、设计模式之间的关系简述

    一.软件体系结构和框架的定义 软件体系结构的英文单词是"architecture". Architecture的基本词义是建筑.建筑学.建筑风格. 软件体系结构虽然根植于软件工程, ...

  5. iOS架构-多工程联编及framework之间的相互调用(19)

    对于大公司,大工程来说,业务线很多,也时刻在变,功能模块要求能随时下线,或者业务不再需要了,就需要从主工程中移除相关工程或者库.以减小包的大小.多工程联编是一种多业务合作的一种方法. 有篇文章写的很详 ...

  6. java状态模式和策略模式_Java状态和策略设计模式之间的差异

    java状态模式和策略模式 为了在Core Java应用程序中正确使用状态和策略设计模式,对于Java开发人员清楚地了解它们之间的区别很重要. 尽管状态和策略设计模式的结构相似,并且都基于开放式封闭设 ...

  7. Java状态和策略设计模式之间的差异

    为了在Core Java应用程序中正确使用状态和策略设计模式,对于Java开发人员清楚地了解它们之间的区别很重要. 尽管状态和策略设计模式的结构相似,并且都基于开放式封闭设计原则,从SOLID设计原则 ...

  8. js 中meta 移除head_JS函数和winform函数之间的相互调用

    1.写一个简单的html页面,用于输入日志,代码如下: <html><head> <meta charset="UTF-8"> <scri ...

  9. 【项目实战——emos在线办公系统】:组件之间的相互使用、请假页面、添加请假组件之间的关系梳理、model和v-model

    一.组件方法之间的调用 1.父组件调用子组件 1.在父组件中:首先要引入子组件 import Child from './child'; 2. <child ref="mychild& ...

最新文章

  1. rabbitmq 查询版本_基于rabbitmq解决分布式事务
  2. 【每日一算法】相交链表
  3. Linux 解压后的启动流程分析
  4. python列表常用方法_第24p,必须掌握,列表的常用方法
  5. Minetorch教程
  6. 常用的几种简单的内部排序方法
  7. python 最小二乘回归 高斯核_「机器学习」一文读懂线性回归、岭回归和Lasso回归...
  8. php study 直接显示代码_《细说PHP》第四版 样章 第18章 数据库抽象层PDO 12
  9. 95-40-025-java.util.concurrent-并发容器
  10. 【转】如何查找MySQL中慢查询的SQL语句
  11. c语言love字符怎么打,怎样利用几行简单的c语言代码表白?
  12. coreos mysql_CoreOS 实战:在 UOS上体验CoreOS 操作全记录
  13. 阳明心学在敏捷开发中的应用
  14. 喵的Unity游戏开发之路 - 攀爬
  15. 【JZOJ】 【NOIP2014】【模拟试题】保镖排队
  16. ios申请企业开发者账号的代理_苹果企业开发者账号的申请详解
  17. ZZULIOJ:1156: 单数变复数
  18. 枚举---知识总结----------gyy加以整理以及改为C++方法
  19. 微信银行突破单一模式功能日渐强大
  20. 【PAT甲级真题整理五】1121~1155

热门文章

  1. 【 MATLAB 】randn,rand,randi 之间的区别?
  2. 【Verilog HDL】设计硬件电路时,如何避免生成锁存器?
  3. 小李飞刀:python请你轻轻轻点虐
  4. APAR:MON_OBJ_METRICS=EXTENDED导致IUD性能问题(转载自Db2技术分享)
  5. 人脸识别如何在大型银行中大规模商用?
  6. 安全性神话已不再,首个MacOS勒索病毒现身
  7. 从volatile解读ConcurrentHashMap(jdk1.6.0)无锁读
  8. 谈谈弹性Web托管的“弹性”
  9. 程序员如何写出更好的代码
  10. 此选项卡已恢复的处理过程