一个游戏程序员的代码书写观(一)

来源:互联网 发布:不同后缀域名的区别 编辑:程序博客网 时间:2024/05/16 17:04

一个游戏程序员的代码书写观(一)

故事

游戏中基本都有MessageBox的需求,虽然可以使用OS层面的MessageBox,但是一般而言都不能满足游戏的需求,有鉴于此,我们实现了第一版的定制MessageBox:

public class MessageBoxManager{    public enum Mode    {        Confirm,        ConfirmCancel,    }    public static void ShowMessageBox(                                       string title,                                        string content,                                        Mode mode = Mode.Confirm,                                       Action onConfirm = null,                                       Action onCancel = null                                     )    // implementations}

这个实现感觉还可以,虽然参数总共有5个,感觉有些略多,但是我们有预见性的提供了默认参数,同时我们提供了基本的MessageBox功能,可以设置标题,内容,显示模式以及可能的回调函数,基本不用编写什么使用文档,稍有经验的程序员都可以顺畅的写出使用代码:

MessageBoxManager.ShowMessageBox("Title", "My First Message Box !");

随着初版MessageBox的广泛使用,相关的需求也在不断升级,现在我们需要支持可以主动关闭的MessageBox了,分析需求后我们意识到这是一种新的MessageBox模式,经过一定扩展,我们有了第二版的MessageBox:

public class MessageBoxManager{    public enum Mode    {        Confirm,        ConfirmClose,        ConfirmCancel,        ConfirmCancelClose,    }    public static void ShowMessageBox(                                       string title,                                        string content,                                        Mode mode = Mode.Confirm,                                       Action onConfirm = null,                                       Action onCancel = null,                                       Action onClose = null,                                     )    // implementations}

Mode的类型增加了,并且接口参数也增加至6个,这里似乎已经有些坏味道了,但是毕竟只增加了一个参数,并且也提供了默认参数,使用上的复杂度似乎还可以接受~

很快的,更多的需求又接踵而至了,现在我们又需要定制MessageBox的按钮文字了,按照之前的思路,我们继续往接口中添加参数:

public class MessageBoxManager{    public enum Mode    {        Confirm,        ConfirmClose,        ConfirmCancel,        ConfirmCancelClose,    }    public static void ShowMessageBox(                                       string title,                                        string content,                                        Mode mode = Mode.Confirm,                                       Action onConfirm = null,                                       Action onCancel = null,                                       Action onClose = null,                                       string confirmText = null,                                       string cancelText = null,                                     )    // implementations}

还没等这版MessageBox实现完毕,我们又收到了新的需求:MessageBox需要支持超时!好吧,我们又不假思索的继续添加接口参数:

public class MessageBoxManager{    public enum Mode    {        Confirm,        ConfirmClose,        ConfirmCancel,        ConfirmCancelClose,    }    public static void ShowMessageBox(                                       string title,                                        string content,                                        Mode mode = Mode.Confirm,                                       Action onConfirm = null,                                       Action onCancel = null,                                       Action onClose = null,                                       string confirmText = null,                                       string cancelText = null,                                       float timeOut = 0,                                       Action onTimeOut = null,                                     )    // implementations}

现在,我们之前相对简洁的接口已经变的非常冗长,参数更是达到了惊人的10个,使用上也变得非常困难,虽然提供了默认参数,但是仍然容易产生误用,考虑我们使用新接口来定制确认按钮的文字

MessageBoxManager.ShowMessageBox("Title",                                  "My Customize Message Box !",                                  MessageBoxManager.Mode.Confirm,                                  null,                                  null,                                  null,                                 null,                                 "好的");

不仅长串的null参数让人心烦,而且接口的调用还是错误的:我们不小心将confirmText参数设置给了cancelText……

方法

放弃原接口的默认参数实现方式,转而使用重载的方式来提供多个接口已达到分解功能的目的,虽然仍然存在参数组合过多导致接口数量过多的问题,但是感谢二八原则,在实际的重载过程中,我们可以根据使用情况来达到相对平衡的封装程度,对于第三方的代码,如果遇到类似参数过多的问题,我们也可以借助外观模式等方法做类似的处理

据此我们实现的新版MessageBox:

public class MessageBoxManager{    public enum Mode    {        Confirm,        ConfirmClose,        ConfirmCancel,        ConfirmCancelClose,    }    public static void ShowMessageBox(                                       string title,                                        string content,                                        Mode mode = Mode.Confirm,                                       Action onConfirm,                                       Action onCancel,                                       Action onClose,                                       string confirmText,                                       string cancelText,                                       float timeOut,                                       Action onTimeOut,                                     )    public static void ShowMessageBox(                                       string title,                                        string content,                                        Action onConfirm,                                     )    {        ShowMessageBox(title, content, Mode.Confirm, onConfirm, null, null, null, null, 0, null);        }    public static void ShowMessageBox(                                       string title,                                        string content,                                        Action onConfirm,                                       Action onCancel,                                     )    {        ShowMessageBox(title, content, Mode.ConfirmCancel, onConfirm, onCancel, null, null, null, 0, null);      }    // other useful overrides    // implementations}

准则

函数的参数数量应该尽可能的控制(Rob大叔在《CleanCode》中描述过的一个观点是尽量减少函数参数的数量,最好不要超过三个),但是实际开发中因为需求增加、时间压力等情况,往往会出现函数参数数量增加甚至爆炸的情况,这种情况下可以考虑采取重载等方式进行进一步的封装,同时基于实际的使用情况来达到尽可能的平衡~

简单一句话:遇到复杂度偏高的代码,考虑进行平衡的封装吧!

0 0
原创粉丝点击