当前位置: 首页 > 科技观察

学习使用这种设计模式来思考业务,想想OKR的表现就很难了

时间:2023-03-14 19:52:35 科技观察

大家好,我是网络管理员。该模型已完全更新。没看过的小伙伴可以点击上方和文末的系列合集链接查看。在开始讲今天的设计模式之前,先问一个问题:“贵公司是否使用OKR来管理季度或双月的个人目标和团队目标?”现在越来越多的公司开始用OKR代替KPI来进行目标管理,这两种目标管理体系的具体区别我就不说了,因为我也说不清楚。..哈哈!我们可以简单粗暴的理解,OKR是自下而上的目标设定,而KPI是大boss直接给你拍的目标。但是在实际执行中,也许,我的意思是也许,赚钱和公司一起生活的最关键的商业目标是从上面的老板直接拍给你,只留下一些你自己的积累、进步、成长。/team/company,whichdon'thurtNotItching的目标是让员工自己做决定,并自下而上完成目标设定。对于研发技术人员来说,个人、团队、公司的成长无非就是提升个人技术,优化系统,在公司的技术积累中加入一些方法论的实践。但是,写目标的时候不能写得太低,比如“重构什么流程,改进XXX”,大话直接往上拖是不行的。OKR讲究说话技巧,让别人看了会激动,让别人会想:“我早就想到了。我一直在等你详细地提出来。”..这个人就是你的直接leader,因为大概率只有他才能看懂你的OKR,上级的人不太可能看懂你的OKR。可能有人会问,我是来找你学设计模式的,你跟我半天OKR目标管理干嘛?这个你不懂,如果你能把流程重构,看似普通的,提炼成用XXX设计模式重构XX流程,增加其无限扩展业务逻辑的能力,结合XXX设计模式减少XX业务重复开发率提高了人的效率XXX,这是不是给人一种完全不同的感觉,那么这种设计模式真的能达到你说的效果吗?如果你的领导几年没写过代码,那他很有可能不知道是的,但是这些设计模式在业界是非常有名的,但是知道有设计模式的人都会觉得你的目标很好的。当然,我不是来教大家跳舞的,而是如何结合实践来表达一些理论的东西,比如UML,GoF23设计模式,DDD中的一些模式。方法论,如果拿出来,会让人觉得非常专业可靠。可以表达的前提是我们要知道,真正去思考什么样的设计模式可以解决当前系统的痛点,接下来我们就进入我们学习设计模式的正题了。所以在这里我先抛出一个我自己总结出来的暴力理论:“模板、策略、责任链三种设计模式是解决复杂多变的业务系统流程痛点的利器”。你可以扩展一下,进一步了解,这三种设计模式也是你在公司里rollOKR的利器。当然,这三个并不是设计模式中唯一的强大工具,但这三个是最基本的。会后,思考的问题立马就不一样了。完全掌握之后再结合更复杂的设计模式也不晚。今天在这里先介绍一下模板模式,因为攻略在步骤中有时会用到模板模式,所以下一篇再分享。我们先来看看模板模式是什么样子的,使用的时候代码怎么写,最后分析一下如何使用模板模式来分析系统目前存在的问题,或者更进一步以及如何设置你的OKR下个季度。什么是模板模式模板模式,有的也翻译成模板方法模式,主要是这种模式中有模板方法,后面在实际应用中会提到,这种模板方法在一些客户端的设计中会用到,服务。在初次交互的场景中,其实是可以虚的。我们可以用自己的意识来设计API,它不必存在于设计模式的类实现中。在做一件事情的时候,这件事情的流程和步骤是固定的,但是每一步的具体实现却不一定。这时候就可以使用模板模式了。模板模式通常的用法是在方法模板方法中定义一个算法或逻辑过程和步骤,比如先调整内部方法A,再调整内部方法B,当满足一定条件时不调整方法C,等等在。流程中每个步骤对应的方法都可以推迟到子类中去实现,这就赋予了程序在不改变大流程和大步骤的情况下完成类似业务的能力。模板模式实现起来非常简单。抽象类用于定义步骤,并提供步骤的默认实现。具体业务逻辑中各个步骤的实现差异可以交给子类实现。模板模式的结构可以用这种方式用UML类图表示。这是我们都见过的业务流程示例。结合代码实现,大家可以更好的理解模板模式的使用方法。如果是Java来实现模板模式,那真的很简单,直接用抽屉类和子类来实现就可以了。网上的资料很多,我就不多说了。接下来,我将使用Go代码来实现模板设计模式。主要原因是Go不支持继承,但是它也有匿名类型。嵌套几乎达到了继承的效果,所以代码会写的有点曲折。模板模式使用示例比如我们去银行柜台办理业务,存款、取款、购买理财等业务流程会包括:取号、排名等号、办理业务、服务评价。如果你是金葵花之类的VIP用户,可能会有一个不用排队的独享窗口,检查用户是否是VIP的步骤叫做hook方法。//本文使用的完整可运行源码//进入公众号「网管必唯」发送【设计模式】接收类型BankBusinessHandler接口{//排队取号TakeRowNumber()//等待aseatWaitInHead()//处理具体业务HandleBusiness()//对服务进行评估Commentate()//Hook方法,//用于判断进程中是否为VIP,实现类似VIP的需求checkVipIdentity()bool}模板方法,因为Go不支持抽象类和子类继承。我们通过匿名嵌套类型来实现这一点。BankBusinessHandler接口的实现通过一个外层类型进行封装组合,达到类似抽象类和子类继承的效果。//本文使用的完整可运行源码//去公众号「网管必唯」发送【设计模式】接收typeBankBusinessExecutorstruct{handlerBankBusinessHandler}//模板方法,处理银行业务func(b*BankBusinessExecutor)ExecuteBankBusiness(){//适用于单次与客户端交互的流程//如果需要多次与客户端交互完成整个流程,//每次交互调整相应模板中定义的方法即可操作,并且不需要调用所有方法的模板方法b.handler.TakeRowNumber()Commentate()}template模式下:存款、取款、银行客户业务之间的关系可以清晰的展示在下面的UML图中:接下来我们可以在子类中实现各个银行客户业务的逻辑,但是无论哪个商业离不开取号、等座、做生意、评价服务的大流程。下面我们使用模板模式来实现存款业务的流程。代码如下:《完整可运行源码,私信发送给公众号“网管叮咚”发送【设计模式】接收》typeDepositBusinessHandlerstruct{*DefaultBusinessHandleruserVipbool}//通用方法也可以抽象成BaseBusinessHandler组合成具体的实现类,减少重复代码(达到类似子类继承抽象类的效果)strconv.Itoa(rand.Intn(100))+",注意排队情况,三个排号过后顺延")}func(dh*DepositBusinessHandler)WaitInHead(){fmt.Println("等待中line...")time.Sleep(5*time.Second)fmt.Println("请转到窗口xxx...")}func(*DepositBusinessHandler)HandleBusiness(){fmt.Println("账户存储很多人民币...")}func(dh*DepositBusinessHandler)CheckVipIdentity()bool{returndh.userVip}func(*DepositBusinessHandler)Commentate(){fmt.Println("请给我的服务打分,满意请点击0,满意请按0,(~ ̄▽ ̄)~")}的过程执行存款业务由外部封装类定义的统一模板方法发起调用。funcNewBankBusinessExecutor(businessHandlerBankBusinessHandler)*BankBusinessExecutor{return&BankBusinessExecutor{handler:businessHandler}}funcmain(){dh:=&DepositBusinessHandler{userVip:false}bbe:=NewBankBusinessExecutor(dh)bbe.Execute}BusinessBank()不时,我们会发现,对于排队取号、等位、服务评价等方式,各种银行服务的实现都是一样的。所以可以把它们放在抽象类中,进一步降低代码的重复率。但是Go并不是一门完全面向对象的语言,但是我们可以使用匿名嵌套的类型组合来达到类似的效果。这些操作的方法由DefaultBusinessHandler类型实现,再由具体的实现类进行组合,这样也可以减少重复实现相同逻辑的效果。"完整的可运行源码,私信公众号"网管叮咚"发送【设计模式】获取"typeDefaultBusinessHandlerstruct{}func(*DefaultBusinessHandler)TakeRowNumber(){fmt.Println("Please拿上你的Pickupcode:"+strconv.Itoa(rand.Intn(100))+",注意排队情况,传号后三个安排顺延")}func(dbh*DefaultBusinessHandler)WaitInHead(){fmt.Println("排队等号...")time.Sleep(5*time.Second)fmt.Println("请转到窗口xxx...")}func(*DefaultBusinessHandler)Commentate(){fmt.Println("请告诉我,满意请按0,满意请按0,(~ ̄▽ ̄)~")}func(*DefaultBusinessHandler)CheckVipIdentity()bool{//returnfalse具体实现类}funcNewBankBusinessExecutor(businessHandlerBankBusinessHandler)*BankBusinessExecutor{return&BankBusinessExecutor{handler:businessHandler}}注意上面的DefaultBusinessHandler并没有实现我们要留给具体子类的HandleBusiness方法,所以DefaultBusinessHandler不能看作是BankBusinessHandler接口的实现。这样做是针对这个类型只能用来封装实现的类,这样Go语言的类型检查可以帮助我们强制要求HandleBusiness方法必须用存款或取款等子类来实现,这样整个银行的业务流程都可以运行。本文完整源码,已同步收录在我整理的电子教程中,您可以发送关键词【设计模式】到我的公众号「网络管理叫哔哔」获取。使用模板模式并不一定推荐有模板方法。这里,我们例子中定义模板方法的方法适用于与客户端单次交互的过程。typeBankBusinessExecutorstruct{BankBusinessHandler}//模板方法,处理银行业务func(b*BankBusinessExecutor)ExecuteBankBusiness(){b.TakeRowNumber()if!b.CheckVipIdentity(){//VIP不需要等待b.WaitInHead()}b.HandleBusiness()b.Commentate()}如果需要和客户端进行更多的交流只需一次交互即可完成整个流程,每次交互操作都可以使用模板中定义的方法。这时候,没有必要定义一个调用所有方法的模板方法。在这种情况下,也可以理解为整个流程使用RESTfulAPI接口的组成,起到了模板方法的作用。互联网C端产品中的典型应用场景,如:用户管理活动API,所有活动可以抽象为:展示活动信息,奖品信息,判断用户资格,参与活动,抽奖,查看中奖记录,以及注销这些步骤的奖品。那么我们可以使用模板设计模式来抽象业务流程,让各种用户活动可以使用一套统一的RESTfulAPI来支撑业务效果。模板和工厂的结合是这里的另一点。在实际开发中,没有一种设计模式是可以独立应用的。很多时候,结合使用几种设计模式来实现项目设计。影响。但是,流程的实现逻辑被模板模式推迟到了子类中。我们大概可以想象,将创建模板子类的任务交给工厂模式更合适。我们应该使用什么样的工厂?一般来说,一个简单的工厂就可以了。在项目之初,一般情况下,我们还没有充分挖掘业务需求和流程,所以一开始不要做太深的细化和抽象,真正需要的时候再升级到抽象。工厂也是必须的。模板方式的优缺点模板方法方式的优缺点使用模板方法将相同处理逻辑的代码放在抽象父类中,可以提高代码的复用性。将不同的算法逻辑分离到不同的子类中,通过扩展子类增加新的行为,提高代码的可扩展性。将不变的行为写在父类上,去掉子类的重复代码,提供良好的代码复用平台,符合开闭原则。模板方法模式的缺点由于继承关系本身的缺点,如果父类增加一个新的抽象方法,所有的子类都必须重新更改。模板模式这么好,那我们是不是要把它应用到所有进程中呢?当然不是,经过大量的实践,能够将某个核心流程提炼成固定的步骤,才更适合应用。如果细化不到位,就不得不频繁地增加或修改流程中的步骤——即修改表示流程的抽象类中的接口或方法。这时候,如果现有业务中流程的实现类有多个,那么都得做相应的调整。模板模式与OKR的结合学习了模板模式之后,我们就来说说如何以这种设计模式的思想为指导,让你发现现有业务系统中需要改进的流程。互联网公司,在某项业务刚刚起步的时候,可以简单粗暴,先上线。哪怕业务前期有很多类似的流程,代码重复率很高,也没关系。理解和抽象到位后,就可以积极思考如何通过模板模式优化流程。就像上面提到的经典例子,在大多数互联网公司的产品生态中,都会有一些用户活动来促进激活,吸引新用户,提高客单价。实现形式往往是植树、抽福袋、抽旋转木马等。是的,在业务发展初期,由于此类活动的形式较多,程序员不知道产品这两天会策划什么活动内容,所以它一般是一组API和一组类用于一个活动。那么这个时候可以尝试使用模板模式的思维方式,想一想找出这些类似的业务有共同的步骤,是否可以把每一个类似的业务都实现到这个模板上的步骤中去,如果没有,继续思考和完善。假设你的公司刚好使用OKR进行续约管理,那么你可以针对提炼核心流程,减少重复代码开发量,提高同类业务上线效率,写进OKR。不仅提升了我们的技术流程抽象设计能力,同时也向上管理了组织对我们的期望。向上管理不是很好吗?