分享一些东西,也求助一些东西
最近碰到了一次工作上的考核,大概的需求做一个消息统一管理,大致包括微信,短信,微博等信息的消息来源统一管理。****** ,当时其实是那么一点点思路,不就是设计模式用适配器模式嘛,把不同的接口适配起来就行了,只是想的简单确不知道怎么敲键盘,周末的时间个人认为有更重要的事就搁浅到了现在。终于在平时看了那么多的设计模式之后还是在今天下午动键盘敲了一些代码,敲完之后心里总是觉得到底应该不应该是这样,却不知道应该是怎么的。下面贴一下个人思路,希望有哪位过来的大神指点指点。
1.适配器抽象类,本来这里一开始按照网上看的例子,应该是要用接口形式的,但是考虑到不同消息发送需要不同的实体,就考虑用的抽象类
/// <summary> /// 适配抽象类 /// </summary> public abstract class Adapter<T> { /// <summary> /// 发送消息请求 /// </summary> /// <returns></returns> public abstract string Send(T entity); /// <summary> /// 注册 /// </summary> /// <returns></returns> public abstract string Register(); } }
2.短信接口
/// <summary> /// 发送短信接口 /// </summary> public interface ISmsSend { /// <summary> ///发送短信请求 /// </summary> /// <param name="entity">短信实体</param> /// <returns></returns> string SendSms(KltxSmsEntity entity); /// <summary> ///注册/更改回调地址 /// </summary> /// <returns></returns> string RegisterSms(); }
3.短信适配器类
/// <summary> /// 短信适配类 /// </summary> public class SmsAdapter : Adapter<KltxSmsEntity> { private readonly ISmsSend _iSmsSend; public SmsAdapter(ISmsSend iSmsSend) { _iSmsSend = iSmsSend; } /// <summary> /// 发送短信请求 /// </summary> /// <returns></returns> public override string Send(KltxSmsEntity entity) { return _iSmsSend.SendSms(entity); } /// <summary> /// 适配短信注册接口 /// </summary> /// <returns></returns> public override string Register() { return _iSmsSend.RegisterSms(); } }
4.短信接口实现类,这里的代码引用了其他系统的一个实例。
/// <summary> /// 短信发送类 /// </summary> public class KltxSmsSend: ISmsSend { /// <summary> /// 注册/更改回调地址 /// </summary> /// <returns></returns> public string RegisterSms() { var registerClient = new KLTX.SMS.SmsRegisterService.RegisterClient(); var rand = registerClient.getRandom(); var url = ConfigurationManager.AppSettings["GfSmsUrl"]; var ucName= ConfigurationManager.AppSettings["ucName"]; var connId = registerClient.setCallBackAddrV2(ucName, CryptographyHelper.GetMd5Hash(rand + KltxAccount.UcPw + KltxAccount.UcPw), rand, url, "3.0"); return connId; } /// <summary> /// 发送短信请求 /// </summary> /// <param name="entity">短信实体</param> /// <returns></returns> public string SendSms(KltxSmsEntity entity) { var registerClient = new KLTX.SMS.SmsRegisterService.RegisterClient(); string rand = registerClient.getRandom(); var sentClient = new KLTX.SMS.SmsSendService.SendSMSClient(); byte[] bytes = Encoding.Default.GetBytes(entity.Content); string contentBase64 = Convert.ToBase64String(bytes); entity.ConnId=ConfigurationManager.AppSettings["ucConnId"]; string result = sentClient.sendSMSV3(KltxAccount.UcName, CryptographyHelper.GetMd5Hash(rand + KltxAccount.UcPw + KltxAccount.UcPw), rand, entity.CalleeArray, entity.IsReturn, contentBase64, entity.MsgId, entity.ConnId, entity.Charset,entity.SignCont); return result; } }
5.加密解密帮助类
/// <summary> /// 加密 /// </summary> public class CryptographyHelper { private const string KeyStr = "Topevery"; private static DESCryptoServiceProvider key = null; static CryptographyHelper() { key = new DESCryptoServiceProvider(); key.Key = Encoding.UTF8.GetBytes(KeyStr); key.IV = Encoding.UTF8.GetBytes(KeyStr); } /// <summary> /// 加密 /// </summary> /// <param name="plainText"></param> /// <returns></returns> public static string Encrypt(string plainText) { try { // Create a memory stream. MemoryStream ms = new MemoryStream(); // Create a CryptoStream using the memory stream and the // CSP DES key. CryptoStream encStream = new CryptoStream(ms, key.CreateEncryptor(), CryptoStreamMode.Write); // Create a StreamWriter to write a string // to the stream. StreamWriter sw = new StreamWriter(encStream); // Write the plaintext to the stream. sw.WriteLine(plainText); // Close the StreamWriter and CryptoStream. sw.Close(); encStream.Close(); // Get an array of bytes that represents // the memory stream. byte[] buffer = ms.ToArray(); // Close the memory stream. ms.Close(); // Return the encrypted byte array. return Convert.ToBase64String(buffer); } catch (Exception) { return string.Empty; } } /// <summary> /// 解密 /// </summary> /// <param name="value"></param> /// <returns></returns> public static string Decrypt(string value) { try { // Create a memory stream to the passed buffer. byte[] cypherText = Convert.FromBase64String(value); MemoryStream ms = new MemoryStream(cypherText); // Create a CryptoStream using the memory stream and the // CSP DES key. CryptoStream encStream = new CryptoStream(ms, key.CreateDecryptor(), CryptoStreamMode.Read); // Create a StreamReader for reading the stream. StreamReader sr = new StreamReader(encStream); // Read the stream as a string. string val = sr.ReadLine(); // Close the streams. sr.Close(); encStream.Close(); ms.Close(); return val; } catch (Exception) { return string.Empty; } } /// <summary> /// 将字节数组转换成字符串 /// </summary> /// <param name="bytes"></param> /// <returns></returns> private string BytesToString(Byte[] bytes) { char[] chars = new char[bytes.Length]; for (int i = 0; i < bytes.Length; i++) { chars[i] = (char)bytes[i]; } string result = new string(chars); return result; } /// <summary> /// 将字符串转换成字节数组 /// </summary> /// <param name="value"></param> /// <returns></returns> private Byte[] StringToBytes(string value) { byte[] bValue = new byte[value.Length]; for (int i = 0; i < value.Length; i++) { bValue[i] = (byte)value[i]; } return bValue; } public static string GetMd5Hash(string value) { MD5 md5 = new MD5CryptoServiceProvider(); byte[] hashByte = md5.ComputeHash(Encoding.Default.GetBytes(value)); StringBuilder sb = new StringBuilder(); foreach (byte b in hashByte) { sb.Append(b.ToString("x").PadLeft(2, '0')); } return sb.ToString(); } public static bool CompareHashVale(string orginValue, string hashValue) { return String.Compare(GetMd5Hash(orginValue), hashValue, StringComparison.OrdinalIgnoreCase) == 0; } }
6.短信实体类
/// <summary> /// 短息实体类 /// </summary> public class KltxSmsEntity { /// <summary> /// 发送短信号码 /// </summary> public string Callee { set; get; } private List<string> _calleeList = new List<string>(); /// <summary> /// /// </summary> public string[] CalleeArray { get { if (string.IsNullOrEmpty(Callee)) return null; foreach (var cal in Callee.Split(';')) { _calleeList.Add(cal); } return _calleeList.ToArray(); } } /// <summary> /// 短息内容 /// </summary> public string Content { set; get; } /// <summary> /// 终端Id /// </summary> public int MsgId { set; get; } /// <summary> /// 链接Id /// </summary> public string ConnId { set; get; } = ConfigurationManager.AppSettings["ucConnId"]; /// <summary> /// 是否需要回执 /// </summary> public string IsReturn { set; get; } = "0"; /// <summary> /// 短消息内容编码方式(0:ASCII、 8:Unicode、 15:GBK) /// </summary> public int Charset { get; set; } = 0; /// <summary> /// 短信签名内容 /// </summary> public string SignCont { get; set; } }
7.方法调用
ISmsSend iSmsSend = new KltxSmsSend();
SmsAdapter smsAdapter = new SmsAdapter(iSmsSend);
KltxSmsEntity entity = new KltxSmsEntity
{
Content = "123",
Callee = "183xxxxxxxx",
MsgId = 3766,
SignCont = "123"
};
smsAdapter.Send(entity);
微信的代码就不上了,大概就是这样的思路,如果第一步没有错的话,接下来一个做的是消息发送记录本地存储,消息记录自动巡查匹配对应的消息类型进行发送接收,以及后续消息缓存,数据分离,因为这还是理论过程中,就可以多想一些。
其实写到现在都有一点没有明白,为什么一定用适配器模式,节省的资源是在什么地方,这样写的好处是在什么地方,易于扩展还是便于维护?
希望能有哪位前辈能够指点一下,非常感谢了!