草庐IT

谈谈我工作中的23个设计模式

轻风博客 2023-03-28 原文

 

 

从基础的角度看,设计模式是研究类本身或者类与类之间的协作模式,是进行抽象归纳的一个很好的速成思路。后面阅读设计模式后,为了加深理解,对相关图片进行了描绘和微调。从技术的角度已经有很多好的总结,本文会换一种角度思考,既然设计模式研究的是类与类的关系,我们作为工作的个体,一些工作中的策略是不是也可以进行类比,可以更好地去思考这些模式?答案是肯定的。

创建型模式 5

 

抽象工厂(Abstract Factory):多套方案

 

抽象工厂模式是对创建不同的产品类型的抽象。对应到工作中,我们的确应该具备提供多套方案的能力,这也是我们常说的,要提供选择题。当你有这样的前瞻意识,一般也会被打上思考较多的标签,但是内在来说,的确想问题更加全面了。

 

 

 

生成器(Builder):善于分解

 

生成器模式是对一个个体的创建过程进行细分,拆解为不同的创建部分。这个对应到工作中,作为一些项目管理人员或者团队管理者,需要将一个大泥球一样的事务,合理分解,让大家各司其职,充分发挥才能。同样,我们对日常的工作内容,也可以按照结构去进行划分,从而更有调理。

 

工厂方法(Factory Method):抽象思考

工厂方法模式是说将提供某一产品的过程进行抽象,通过接口的模式去规范出来。类似的,我们很多做事的过程,都是面向过程,没有抽象提炼一下。如果经过进一步思考,那么可以往上再提炼一个层次,发现事物的本质:到底在做什么,我们的职责是什么,提供什么样的价值。想的更清楚,做的也会更加准确。

 

 

 

原型(Prototype):传承知识

原型模式是说,利用拷贝对象的方法,减少一些复杂的创建过程。这里我们能够学到的是,需要做好日常的积累,很多方案不是每次来都重写,是可以在原来的方案上进行拷贝复用的。这个clone的过程,往往也是知识传承的过程。如果有比较好的传承机制,那么会大大提升服务效率。

 

 

 

单件(Singleton):专注

单件模式是说在多线程的情况下,要保证对象只创建一遍,作为独一无二的资源。这个我觉得,应该去review一下我们的工作模式,虽然我们常常要并发很多事情,但是如果处处被打断,每件事都想干好,那么可能每件事都干不好。我们要确保在某个时间段竭力地做好一件事。事件是一件件有效解决的,不是一起慢慢解决的。

 

 

结构型模式 7

 

适配器(Adapter):适应能力

适配器是为了结合原来的能力,适配新的接口服务,比如适配不同的协议入口。工作的时候,其实需要适应不同的人和事,有不同的工作方法方式,但是我们的核心能力是一样的,都是解决对应的问题域。

 

 

 

桥接(Bridge):合理关系

桥接模式是将原来相互依赖的部分,通过上层接口再往抽象层提一下,减少类之间的直接合作,形成间接关系。这个到对应到工作中来说,有一种场景是,常常开发对开发去case by case解决问题。如果往产品逻辑层走一下,开发对产品,产品层面可能有更好的抽象。当然为了更好的服务体验,这样的解耦是不多见的,但是这样的思考我们可能要get一下。

 

 

 

组合(Composite):递归思考

组合模式通过继承和孩子节点,可以递归地去描述一个对象层次。这个对我们工作来说,要加深思考的层次,可以某个点拆开去再去思考,同时如果能够在递归分解过程中抽象一些共性的点,就能找到一些规律。比如我们的需求分解,每个需求可以分解为子需求,子需求再往下看又可以递归分解。分解完之后,每个部分有这部分的owner去驱动他的下游,形成一个层次结构。

 

 

 

装饰(Decorator):增量价值

装饰模式是将原来的能力进行包装,并提供新的行为。其实每次功能迭代,我们大多是在原来的基础上添加新的功能。我们要定义好新的能力,首要前提是继承、理解好原来的逻辑。这里还想提的是,很多时候,我们只看到了我们复用了庞大的基础能力,但是也要看到我们在项目中增量的贡献,这是我们的闪光点。不要把“拧螺丝”真的看成了拧螺丝。

 

 

外观(Facade):深入浅出

外观模式是说我们不需要理解复杂的系统,而是通过一个外观去操作。这里我们的工作思路是,我们不用展示复杂的细节,我们要提供一些高层的理解,汇报如此,系统的包装也是如此。就比如,服务功能孤立来看,可能很多、很杂,但如果有一个统一的站点去引导包装,那么感觉会好很多,也会看上去有点收口和聚焦的感觉。

 

 

享元(Flyweight):善于链接

享元模式是说,当我们已经存在一些内容的时候,可以通过缓存复用,而不是重新创建,减少开销。我们在工作中也要做好积累,但是更要做好缓存的key,通过怎么样的手段去链接到我们的工作中,是需要我们做好类目管理和持续积累的。

 

 

 

代理(Proxy):理解保护

代理是为了包装一个类,对相关操作进行二次转发或者进行一些管控。工作中来说,有些工作模式下,有时候我们可能会抱怨管理者代理了我们的决策等操作,但是换个角度想,他们保护了你不用直接被暴露在业务方侧,能够按照预期内的节奏提供服务,不会被主动设置一些预期外操作或私活。

 

 

行为型模式 11

 

责任链(Chain of Responsibility):能力与责任

责任链是说将请求让队列内的处理器一个个执行,直到找到可以执行的。这里对我们工作的启示是,我们常常抱怨我们得到的机会少,不能成为队列内优先可以处理的处理器,总是处理人家不需要的。但是换个角度看,首先责任链里面的处理器应该是正交的,大家应该各司其职。退一步来说,如果真的有重叠,那么你应该努力提升自己,成为能力强的,从而提高队列内的优先级。

 

 

命令(Command):加强合作

 

命令模型是说将请求包装为命令,这样在执行的时候可以与具体的执行逻辑解耦。工作中来说,我们有时候不应该太关心一个事情是怎么完成的,当交给别人完成时,信任他们即可,就是从解决问题的角度来看,不用事事亲为,事事较真。但是这并不妨碍我们主动养成全局视角,了解每个细节。合作才能影响更多的事情。

 

 

 

解释器(Interpreter):加强理解

 

解释器模式是说针对一套上下文,形成一套语言,可以通过解释表达式含义的方式完成对应的任务。这里来说,我们可以形成某个团体的领域语言,内部交流通过相关领域语言交流,可以增加交流效率。此外,其实不同层次都有不同层次的专业术语,有时候一个术语的解释是一个方面的顿悟,还是要多了解工作内容本身。

 

 

迭代器(Iterator):横向职责

 

迭代器模式是将集合的访问功能独立出来,通过迭代的模式去访问。这种独立职责的操作,工作中我们常常会看到,我们会将需求管理,缺陷管理,资金安全的一些事情独立出来看。一个方面是这些功能块从主体来说是比较内聚的,另一个来方面说,对工作职责的细分,可以让大家把自己的事情干好,发挥团队作战的效能:开发把开发干好,测试把测试干好,资损防护同学把资损防护干好,整体也就做好了。

 

 

中介者(Mediator):协调能力

 

中介模式是说:当多个类之间要协调的时候,往往引入中介者进行协调,减少大家的知识成本。这个我们常常需要一些PM、PMO这样的角色去管理项目,系统中也需要一些协调层去协调各个域。因此我们也注重培养协调事务、具备全局观的能力。

 

 

备忘录(Memento):小步快跑

 

备忘录模式是对操作的一些记录,已被可以恢复到之前的版本。在日常工作中,我们常常需要及时备份、及时保存、及时提交等操作,这样在程序崩溃的时候可以快速恢复到之前版本。但从抽象来说,一些比较长时费力的事情,我们应该分解来做,及时锁住部分收益。

 

 

观察者(Observer):主观能动性

 

观察者模式是说我们通过注册、回掉这样的协作设计,完成变化通知的协作机制。这个工作中来说,换个角度思考,我们可以将一些被动的工作,变成主动的思考。比如:我需要干某部分工作,从工作的角度来说,不得不做,从主动的角度来说,就是需要培养某块的能力。如果对工作内容不太满意,也可以沟通协调,而不是事后爆发,凡是都是可以主观驱动的。

 

 

状态(State):管理自己

 

状态模式是说在不同的状态下,有不同的处理行为。对工作中来说,我们可能有状态好的时候,有状态不好的时候,主观的处理的手段是调整状态。但是如果调整不过来,我们应该进行不同的操作。比如,脑子好的时候,想一些复杂问题;脑子嗡嗡的时候,做一些简单整理。

 

 

策略(Strategy):理解决策

 

策略模式是说完成一个事情有不同的算法,可以进行相关切换。我们在工作中,常常会提供不同的方案,不同的方案有不同的成本和收益,但是这些方案的选择时候,往往不是我们能决定的,而是客户client主动判断的。

 

 

模板(Template):标准化能力

 

模版模式是说对一个执行过程进行抽象分解,通过骨架和扩展方法完成一个标准的主体逻辑和扩展。我们很多时候,做xxx平台也都是这样的:对过程进行标准化,对变化进行定义,形成一个平台逻辑和业务扩展,完成一个产品模版。只是说这个模版是站点,还是扩展点,还是其他的展示形式。这样标准化的能力也是需要长期训练的。

 

 

访问者(Visitor):学会放手

 

访问者模式是说把对元素的访问操作交给访问者来操作,因为对访问者来说常常有不同的访问行为。在工作中,往往我们只能陈述事实,这个内容消化后,每个人都有自己的理解。代码协作也是一样,比如:页面到底长什么样,其实还是要交还给业务本身,我们应该专注于提供基础的能力。

 

 

 

总结

作为开发者,我们对于如何写出优雅的代码,表示疑惑。因为常常背后是复杂的问题域,优雅的设计往往产生于局部,很难整体都很优雅。作为工作者,我们对于如何做出好的表现,表示疑惑。因为背后常常是综合素质与机遇的结合,好的结果往往产生于一个阶段,长期需要较快且持续的成长。但是,如果我们有一些指导性的原则,往往我们能够明白事务的折中点,做出更加合理的设计,以及更加关键的贡献。

 

 

  作者丨闵大为(天未)

有关谈谈我工作中的23个设计模式的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  3. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  4. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  5. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  6. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  7. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  8. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  9. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  10. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

随机推荐