使用了继承、多态还有工厂模式和反射,但是还是没有OO的感觉。[已经增加了实现的代码]

最近项目里遇到了一个问题,为了解决这个问题“动用了”继承、多态还有工厂模式和反射,但是还是没有OO的感觉。呵呵。

先说一下具体情况:
1、使用短信猫来接收短信。简单的说,短信猫收到短信后会往指定的表里面填写数据。
2、接收到短信,然后根据短信前面的“标志”调用不同的方式来处理。
3、发送确认信息或者是错误提示。
4、想做成一个“通用”的模块,不管是什么项目,都可以使用这个程序来处理接收短信的问题。当然具体的处理方式要能很方便的修改或者扩充。

我的实现方式:
1、定义一个基类,用来处理接收到的短信。
2、由于每一种短信的处理方式都不同,所以需要好多的不同的子类。每一个子类来处理一种短信。
3、调用的时候 如果用 case 的方式的话,每增加一总短信都要修改case 。很烦!而且当应用在一个项目里的时候,case 就得推倒重来,烦!
     最后使用了反射。
4、建立了三个项目,一个是winform的用来检查表里面是否有新的短信,叫做A ;一个是处理短信的项目,叫做B;最后一个就是具体的项目了。

==============
说明:
 具体的项目指的是,可能是A公司的OA,可能是B公司的CRM,也可能是C公司的ERP。
 这里说的是分“项目”,而不是分层。
 处理短信的项目要根据不同的公司的不同的需求来编写,写完了之后编译成DLL,交由 A 来调用。
==============

5、其中 A 是通用的,写好了基本不变。B编译成dll,好让A来调用。
6、A 调用处理短信的类。由于使用了反射,可以“动态”的指定dll名称和类名。这样就很灵活了,处理短消息的方式有变化的话,只需要更新dll就可以了。
  换成新的项目的时候,换成新的dll就可以了。这样A就不用改了。

现在基本功能是实现了,但是这样就OO了吗?还是没有OO感觉。

感觉还是在用面向过程的思路来写程序,一个子类里面只有一个函数,和面成过程有什么区别呢?

您可能要问了,那我为什么还要用多态呢?其实很简单,这样就可以使用“反射”了,这样我就不用写case了,可以让A不必随不同的项目而修改了。

说白了就是想当变化的时候少改点代码。

正在看面向对象、设计模式了什么的,把自己的想法、做法写出来,请大家批批。

ps:这里好象用“观察者”更好一点,A就是一个发布者,B是一个订阅者,只是我不知道如何让B来订阅A。
也许根本就不适合吧,毕竟有新的短信了,只有一种处理方法是对应的,其他的都不是。

代码补充:

namespace HBS.SMSReceive
{
    /**//// <summary>
    /// 接收短信。基类
    /// </summary>
    public class MessageReceive
    {
        public DataAccessLayer dal ;
        
        处理短信的函数#region 处理短信的函数
        /**//// <summary>
        /// 接收短消息然后作相应的处理
        /// </summary>
        /// <param name="Mobile">传入手机号</param>
        /// <param name="RecvDate">传入收到短信的时间</param>
        /// <param name="Msg">短信内容</param>
        public virtual string SaveMsg(string Mobile ,string RecvDate,string Msg)
        {
            return "";        //表示正常执行。否则表示出错信息。需要把这个信息发给发送者
        }
        #endregion

        把短信移动到历史记录里面#region 把短信移动到历史记录里面
        /**//// <summary>
        /// 把短消息从inbox 表中移动到历史记录表里面
        /// </summary>
        public virtual void LogMsg(string InboxID)
        {
            //复制记录
            string sql = "insert into InBox_Log (mbno,Msg,ArriveTime,Readed,username,comport) select mbno,Msg,ArriveTime,Readed,username,comport from InBox where id= " + InboxID;
            dal.RunSql(sql);

            //删除记录
            dal.RunSql("delete from InBox where id=" + InboxID);

        }
        #endregion
    }

    子类1:处理没有标志的短信#region 子类1:处理没有标志的短信
    /**//// <summary>
    /// 没有标志的短信
    /// </summary>
    public class MessageOperationOther:MessageReceive
    {
        public override string SaveMsg(string Mobile ,string RecvDate,string Msg)
        {
            return "您发的短信我们无法正确识别,请核对后再次发送,谢谢合作!";
        }
    }
    #endregion

    子类2:MessageOperation01 第一种短信的回执#region 子类2:MessageOperation01 第一种短信的回执
    public class MessageOperation01:MessageReceive
    {
        public override string SaveMsg(string Mobile ,string RecvDate,string Msg)
        {
            //处理第一种短信,代码略

            return "";
        }
    }
    #endregion
}

然后就是A里面的调用的代码

//获取短信内容,放在 DataTable dt 里面
//然后遍历 dt

Assembly.Load("SMS").CreateInstance("SMS.短信" + 短信开头的编号)

代码补充:

处理接收到的短信#region 处理接收到的短信
        private void monitorInSMS()
        {
            string strSQL = "select * from inbox ";    
            DataTable dt = dal.RunSqlDataTable(strSQL);
            string Mobile = "";            //去掉 86 的手机号
            string[] msg = null;        //短信的类型。
            string re = "";                //处理短信后的结果。""表示正确执行。
            
            //遍历短信
            foreach (DataRow dr in dt.Rows)
            {
                Mobile = dr["mbno"].ToString();
                if (Mobile.Length > 11)                //去掉前面的86
                    Mobile = Mobile.Substring(Mobile.Length - 11,11);

                msg = dr["Msg"].ToString().Trim().Split(' ');        //获取短信的标志
                
                //根据标志加载处理短信的实例,在这里省去了 case 。
                msgRecv = (HBS.SMSReceive.MessageReceive)Assembly.Load("HBS.SMSReceive").CreateInstance("HBS.SMSReceive.MessageOperation" + msg[0].Trim());

                if (msgRecv == null)
                {
                    //没有找到对应的分析短消息的类,设置默认选项
                    msgRecv = new HBS.SMSReceive.MessageOperationOther();
                }

                msgRecv.dal = dal;        //设置“数据访问层”的实例

                //处理接收到的短消息
                re = msgRecv.SaveMsg(Mobile,dr["ArriveTime"].ToString(),dr["Msg"].ToString().Trim().Replace("  "," "));

                if (re.Length == 0)
                {
                    //正确执行,发确认短信。
                    msgSend.SendMsg(Mobile,"我们已经收到了您发的短消息,并且保存成功!");
                }
                else
                {
                    //没有正确执行,发送错误信息。
                    msgSend.SendMsg(Mobile,re);
                }
                
                //移动短信,把短信移动到历史记录里面
                msgRecv.LogMsg(dr["ID"].ToString());
                
            }
            
        }
        #endregion

大体就是这样了。

反射还是在看了伍迷的小菜系列才会用的,再此表示感谢。

时间: 2024-09-21 15:27:35

使用了继承、多态还有工厂模式和反射,但是还是没有OO的感觉。[已经增加了实现的代码]的相关文章

面向对象编程设计模式--简单工厂模式讲解

工作之余,在看资料过程中发现一个极易理解的简单工厂模式的例子,自己亲自试练一番,感觉对这个设计模式不熟悉的朋友, 一看马上就知道是什么回事了. 简单工厂模式根据提供给它的数据,返回几个可能类中的一个类的实例.通常它返的类都有一个共同的你类和共同的方法, 但每个方法执行的任务不同,而且根据不同的数据进行了优化. 简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一. 下面进行一个代码示例: public class g

工厂模式----设计模式系列

本文采用了三种工厂模式 简单工厂模式 工厂方法模式 应用反射实现工厂模式 存放说明如下: com.dyk : 包含main方法的测试类 com.dyk.factory : 三种工厂类(具体工厂类的接口或者具体的工厂类) com.dyk.factory.impl : 工厂类的具体实现 com.dyk.operate :  具体运算类的父类 com.dyk.operate.impl : 具体的运算类 一.简单工厂模式      这里需要用到五个类,分别是:OperationFactory.Opera

JavaScript设计模式之工厂模式和构造器模式_javascript技巧

什么是模式 前阵子准备期末考试,劳神又伤身的,实在闲不得空来更新文章,今天和大家说说javascript中的设计模式. 首先呢,我们需要知道的是:模式是一种可复用的解决方案,而反模式呢就是针对某个问题的不良解决方案. js反模式常见例子 1.向setTimeout和setInterval传递字符串,而不是函数,这会触发eval()的内部使用. 2.在全局上下文中定义大量的变量污染全局命名空间 3.修改Object类的原型 4.以内联形式使用js,嵌入在HTML文件中的js代码是无法包含在外部单元

ASP.net 中的页面继承实现和通用页面的工厂模式的实现

asp.net|继承|页面 最近用.Net做web项目的时候遇到了一些问题,就是很多的页面的处理一样的,不一样的就是我们写的存储过程不同,为了考虑代码的重复利用和可维护性和可 扩展性,于是写了一个对于单据页面的工厂模式,采用界面的继承技术,因为我们写的ASP.net页面的是代码后置的,所以我们继承的时候就继承我们的后置的代码,也就是我们说的XXXX.aspx.cs文件.其实页面的继承和我们普通的类继承一样,只是ASP.net页面的界面是HTML和后置代码共同组成的,所以也有一些不同,好了先进开始

《java与模式》----创建模式系列工厂模式、单态模式精讲

创建 创建模式-----Creation  Pattern 创建模式是对类实例化过程的抽象. 一些系统在创建对象的时候需要动态的决定怎样创建对象.创建哪些对象.以及如何组合,表示这些对象.创建模式描述了怎样构造和封装这些动态的决定. 创建模式又分类的创建模式和对象的创建模式. l         类的创建模式:类的创建模式使用继承关系,把类的创建延迟到子类,从而封装了客户端将得到哪些具体类的信息,并隐藏了这些类的实例是如何被创建的和放在一起的.. l         对象的创建模式:对象的创建模

设计模式系列之一:简单工厂模式

前言 设计模式能够帮助我们设计出健壮,低耦合性的代码,从此和高耦合的代码say goodbye!在所有的的设计模式中,简单工厂算是我们平时接触比较多的吧,多线程中的消费者工厂类与生产者工厂类应该算是接触最早的设计模式,简单工厂模式要解决的首要问题就是降低程序之间的耦合度,通过Java中的封装.继承与多态实现解耦.通过使用简单工厂模式,我们设计的代码更易于维护和复用 问题背景 在进入正题之前我们先看一下问题背景: 某公司开发了一个A软件,数据库使用的是SQLServer.后由于客户要求需要使用Or

简单工厂、工厂方法、抽象工厂模式

           最近一直再将设计模式,于是趁热打铁,对这三种设计模式做一个总结.           首先我先用一句话总结一下这三个模式:简单工厂是一个工厂只能造一种奔驰,工厂方法是一个工厂可以造多种车,比如劳斯莱斯.奥迪等,而抽象工厂是说工厂不光可以造越野式奔驰,还可以造家用式奔驰.还有商用式奔驰.            那么究竟简单工厂是什么呢?为什么它不是23的设计模式中的一个?            用一个类图和一段代码我们来解释一下:                      

设计模式: 简单工厂模式

引入: 在我们的思维中,会有一种习惯,当遇到某种问题时,会直接考虑用最直接的语言去去实现它,而往往忽略了整个程序的可维护性.可扩展性. 比如,我们写一个基本的计算器功能,要求能计算四则运算,大家或许会直接写: public class ProgramDemo{ public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(

简单工厂模式--加减乘除运算

下面基于简单的<加减乘除运算>实例来讲讲实用简单工厂模式:<备注:以后根据认识的加深,可以添加和修改内容> 需求分析:希望程序提供"加减乘除"四种功能. 功能分析:四种功能都是并列的,相互独立的. 拓展分析:很有可能拓展新的功能,比如"开根运算". 如何设计: 1.根据"功能分析"可以将四种功能都归并一个父类出来,然后创建四个子类继承它,并且提供空的方法(OC中模拟抽象方法或者虚函数),这四个子类分别都要继承并重写实现这个