设计模式之间可以相互"功能替换"吗?_dhka8040652的博客-程序员宅基地

技术标签: 设计模式  

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

 

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

 

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

 

    策略模式的类图如下:

 

 

      工厂方法模式的思想:

 

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

 

     该模式中包含的角色及其职责工厂(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

转载于:https://www.cnblogs.com/ASPNET2008/archive/2008/04/25/1170602.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/dhka8040652/article/details/101460087

智能推荐

idea下的spring boot remote debug 启动办法-程序员宅基地

最近做个spring boot的项目,因为涉及到dubbo,采用的是 spring-boot:run 启动的工程下面的图那个样子

一个拿到人人网和淘宝网offer的大四学生的Android学习经历-程序员宅基地

本来早就应该整理好的,但是最近一直杂事比较多,现在在家,我家不能上网,在亲戚家用网,总算整理好了。我也着急啊。因为过几天就要去实习了,所以,今天无论如何,总算整理好了。高兴ing....我整理的东西呢,都是我从8月1号开始写得,我基本都看过,我希望学习安卓开发的朋友都看看,很好的。不知说什么了,大家自己看看, 有能帮上您的,是我最大的荣幸。下面附上我的联系方式,有问题的可以联系我哈

【每日打卡】Day2:众数问题的Java实现_众数问题算法分析java-程序员宅基地

众数问题,将数组排序后转换为字符串,再采用字符串的性质,获取重复元素个数,代码运行效率较高import java.util.*;public class Main { public static void solve(int arr[]){ Arrays.sort(arr); List<Integer> list = new Array..._众数问题算法分析java

为什么说前端开发难?前端开发难在哪里?_前端开发过程中遇到的难点_汇智知了堂的博客-程序员宅基地

前端开发上手门槛相对较低,学习难度也不高,但为什么前端工程师仍然这么吃香呢?为什么很多公司还找不到前端呢?我们就来聊聊前端开发的难点在哪里?当你有这个问题时,说明你在开发工作中遇到了瓶颈,这是好事,说明你有进步的机会了。第一,不同级别的前端面临的难点不尽相同,前端开发中的困难也不能一概而论。有的人觉得CSS简单,也有很多人觉得CSS难,讨论到这样的争论毫无意义。前端涉及的内容广,办法总比问题多。可能对于P5的前端来说,业务代码是现阶段的难点,如何解决灵活性、适配性等问题是当前的难点。而对P6来说,如何用_前端开发过程中遇到的难点

openGL学习之旅(一)DEV-C++安装GLUT_c++工程导入glut.h-程序员宅基地

最近公司一直没事情做,就开始逛论坛关注一些东西。无意中又看到了android游戏引擎的资料,于是突发奇想的开始想学下openGL。个人感觉这个应该是学习游戏引擎的一个基础吧。刚好最近也在看《the c programming language》,所以打算从C语言入手学习opengl.也许java做久了,特别的不喜欢微软的开发界面,所以决定用自己比较喜欢的DEV-C++。DEV-C+_c++工程导入glut.h

随便推点

Xcode生成的可执行文件在哪里!-程序员宅基地

很多iphone、ipad、xcode、mac os x初学者编了半天程序,结果找不到生成的可执行文件在哪里。实际上生成可发布的可执行程序需要进行一些设置。首先启动xcode,单击Xcode &gt; Preferences菜单项,打开Preferences对话框,切换到最后一项“Location”,Derived Data旋转Custom,选择要存储目标文件的目录。如图1所示 图1 单击A...

【二】Springboot常用的maven坐标-程序员宅基地

springboot开发中常用的依赖版本号1.整合jsp做视图的依赖2.整合mybatis的依赖3.整合阿里数据源druid的依赖4.oracle数据库的依赖5.lombok注解依赖6.md5依赖7.文件上传下载依赖8.支持热部署的依赖9.AOP开发的依赖10.JavaEE规范的依赖版本号<properties> <!--springboot应用要求jdk最低1.8版本--> <java.version>1.8</java.version>

Android 实现USB转串口通信_android usb串口通信_Science Desert的博客-程序员宅基地

目前我正在使用工业安卓平板做上位机,工业安卓平板带有232、485串口以及USB接口,通常驱动232、485接口需要有厂家提供的JNI库以及相关的java类。某天浏览Android Developers开发者指南时,看到了关于USB使用的文档,因此想参考文档做USB转串口的通信实验,但实验的过程中遇到了不少问题,特此记录。说明一下实验所用的硬件:1.工业安卓平板(带有USB接口)2.USB转TTL数据线(芯片型号PL2303HXD)遇到的问题首先USB转TTL线插到工业安卓平板的USB口,然后根据_android usb串口通信

MAc studio快捷键-程序员宅基地

文章参考地址:http://blog.csdn.net/zclengendary/article/details/52498522mac下android studio 常用快捷键常用插件1.下载插件方法:打开Preferences界面,点击Plugins,点击Browse repositories...,在文本框输入插件名称敲enter键,点击插件详情页面的instal

STM32——USB详细使用说明 附件HID的双向通信_stm32 usb枚举过程详解-程序员宅基地

转自:http://blog.sina.com.cn/s/blog_98ee3a930100wn6m.html说明:使用的是STM32F103ZET6硬件原理图在开始枚举设备的一些初始化void bsp_USBInit(void){ GPIO_InitTypeDef GPIO_InitStructure; RCC_stm32 usb枚举过程详解

爱奇艺2018春招Java工程师编程题题解-程序员宅基地

爱奇艺2018春招Java工程师编程题题解 字典序最大子序列题目描述对于字符串a和b,如果移除字符串a中的一些字母(可以全部移除,也可以一个都不移除)就能够得到字符串b我们就称b是a的子序列。例如."heo"是"hello"的子序列,而"xl"不是。对于给定的一个字符串s,请计算出s的字典序最大的子序列。输入描述:输入包括一行,一个字符...

推荐文章

热门文章

相关标签