书写正确的代码

【我的OpenGL学习进阶之旅】 C++ 长行字符串多行书写的方法以及如何书写正确的OpenGL Shader着色器代码 1. 如何在C++中书写多行字符串 2. OpenGL该在哪里书写正确的shader着色器代码 阅读详情

    写下这个标题的时候我就在想,正确的代码?能够按要求正确地运行,不就是正确的代码吗,如果这些代码还具有较高的性能,那么甚至还能被称作非常正确。其实这是不准确的,如果代码是方便面,吃完就可以丢到垃圾桶里,我想这么理解就很不错了。但事实上,一份代码可能在写成之后,需要不断修改、升级发布新的版本,而在这个过程中会有很多人加入其中,所以在多次易手之后,代码能够让别人快速理解,那么清晰的逻辑结构以及良好的可读性才是衡量正确的标准。

    但这个问题的解决方案我们并不陌生——Architecture。但是这个词压下来总让很多coder觉得面临了一个难题:啊,我要怎样在看清海市蜃楼前画出海市蜃楼?踌躇中不由得手心出汗。至少我是这么觉得的。我相信,即便是有这样能力的那些架构师们,也不是来自于氪星球,生来就有超能力的。如果你喜欢抬杠,非要说Knuth很小的时候就能够把计算机当作打印机,只是把脑子里的宏图复写下来而已,那我只好服输:赛亚人也不算数。那么为了不讲鬼故事吓跑小朋友,其实可以将架构换成一个亲民一点的词,设计模式。这个东西大家一定都耳熟能详,它们其实就是匠人手里小工具,能够帮助我们更好地搭一座像模像样的小屋。刚接触设计模式的时候,发现大大小小几十个模式虽然多,但其实都不难理解,然而到自己实际开始书写代码时,发现这些模式对我一点帮助也没有,代码自成一体,好像没有必要或者不能使用一些模式,总不能为了使用设计模式而使用设计模式吧。嗯,最后这个观点是正确的。我觉得这个时候其实是离程序太近了,两个月之后回来再看看,想法可能就有所改观了。

    Graham认为,程序员和画家在本质上是一样的,画家或者说画手在绘制作品的时候仅仅有一个主题和大概的布局,在一笔一笔添加到画布上时也同时在填充画手心里的构思。编程的过程就是和程序对话的过程,书写的过程就是思考的过程,在不断编写的过程中代码才逐渐丰满起来,不要企望在写下第一个int的时候,整个程序的轮廓都清晰可见,程序的结构是一步步修改完善的,架构师也是一点点养成的。好像有点扯远了,那么我们回到主题上,设计模式能帮助我们写出正确的代码。可是怎么用呢?这就是上面大段口水想要表达的内容,在编写的过程中时刻警觉所遇到的困境,并且思考使用优雅的方法来解决,自然地融入设计模式,揣摩理解架构的核心理念。

  我就来举个小例子吧。在完成一个程序的编写后,没有进行整体的调试,也许你会说,天呐,竟然没有调试。遗憾的是,这就是事实。因为这个程序需要和真实设备进行大量的服务交互,而模拟环境下无法提供这些服务,糟糕的是,我要等一个月才能有这样满足条件的设备,所以唯一能做的就是在模拟环境下测试一下UI的流程。而测试UI的手段相当原始,相信任何心理健康的人都会像在帝国大厦顶上看到金刚一样惊讶,是的,我将所有需要调用服务的代码都临时注释掉。我承认这是我在java环境下没有找到类似条件编译这样的方法而采取无耻手段,但好在我很快就停止这种令人羞愧的行径。因为,我不但需要在代码中加入一些仅仅为了调试的测试语句,更可怕的是,出去喝了一杯咖啡之后,我自己也忘记了哪里被注释掉了最后应该还原回去。

    在意识到这种暴力是无益于和谐社会之后,我开始思考如何在上设备前进行比较全面的测试,幸运的是在等待设备前我有足够发呆的时间。我首先想到的是,可以构建一个模拟的服务,在测试的时候使用这个模拟的测试服务(TestService),在真机测试时再切换成真正的设备服务(RealService)。那么,现在我需要做的,仅仅是将使用设备服务的代码修改成是使用测试服务,即

RealService.doService() ---->TestService.doService()

   其他的代码都不需要修改,我仅需要作一个Ctrl+H的操作就可以了。可是做这种危险的替换,我想我晚上会担心得睡不着觉的。所以,为何不将实现抽象出来呢?就像无数教科书上说的:面向接口编程而不要面向实现。


    可能在第一步时候你就想到这么做了,想要我承认你比我聪明,别做梦了,这不是自命不凡的程序员干的事儿。话说回来,好像现在要好多了,代码中出现使用服务的地方都是用了顶级服务,类似于IService.doService(),是的,仅需要在获取服务的地方切换真实服务和测试服务,事情终于变得合理了一点。而且,似乎可以利用依赖注入模式(DependencyInjection)来将设计变得更漂亮一点。为什么不呢?我修改了代码,从统一的入口处获取服务,而服务此时使用了IService接口进行了抽象,整个程序根本不知道使用的是真实服务还是测试服务,我自己配置决定具体注入的是RealService还是TestService。

    如果我就此打住,相信很多人会说,嗯,你说得很对,但等等,怎么做啊?是的,我自己的代码,只能我自己来设计。难道要丢给测试团队的小妹妹,那么任何人都会责怪我的。好吧,我希望在配置文件里写上程序运行模式,比如run_mode=test,那么程序就会建立测试服务并注入到请求服务的地方。那么现在我需要一个创建者,请求服务的代码只认识这个服务创建者,它向这个创建者说,喂,我要服务!然后这个创建者说好,他看了一看配置文件里的run_mode=test,然后拿起一个测试服务给请求者,说:给你服务!是的,事情就这么简单,我当时脑子里就是这么想的,我希望这样说你已经明白了,这就是一个抽象工厂模式(Abstract Factory)。


    服务请求者保持了一个ICreator(我使用了Creator而不是Factory是有原因的)引用,当请求者需要使用服务时,ICreator根据配置文件决定使用的是测试服务创建器(TestServiceCreator)还是真实服务创建器(RealServiceCreator),然后它们各自生产自己的服务交付给请求者,完成了简单的依赖注入。

    现在先暂停一下,回顾一下现在的设计,从最初的直接获取并使用服务,到现在是用创建器获取服务,中间涉及的对象增加了,似乎增加了程序的复杂度了。不过事实上,程序现在更美观正确了,服务使用者和服务的获取分离开了,我终于可以开始进行主程序的调试而不必担心被你嘲笑了。如果以后需要修改服务,或者添加新的服务,那么仅需要添加新的服务及其创建器就好了,服务的调用代码是不需要更改的。降低系统的耦合,提高系统的扩展能力,这就是无数现行开发框架的核心目的,理解这个中心思想(这让我想起了小学语文老师),再去掌握这些开发框架,它们才能被融汇成自己的内功而不是手中的冷兵剑。

    事情到了这里似乎是完美了,但等等,还有点教科书之外的东西。有一个服务它很特别,我要说“特别”真是一个terrific的词,如果你说一个女孩很特别,我知道你是爱上她了,她肯定在某方面很吸引你,但如果在编程的时候遇到特别的东西,就是值得头疼的事了,它意味着你得使用专门的代码进行特殊处理。这个令人头痛的东西就是服务A,这个服务需要请求者逐渐填充一些配置参数,最后再使用根据这些配置参数获得的服务,如:

serviceA.config(param);

serviceA.doService();

    逐渐填充,这个要求毁了我之前全部的设计,但我稍后又镇定了下来,我不希望因为一个特殊的要求而退回之前糟糕的设计。但这个逐渐填充,让我想到了另一个设计,生成器(Builder)模式。它要解决的设计问题就是这种逐渐生成的对象创建模式,那么好吧,就将工厂模式和生成器模式结合起来吧,这就是我将之前的创建器命名为Creator的原因,因为它既不是Factory也不是Builder。基本的思路是请求者向创建器提交服务请求,并且一步步配置创建器,最后创建器根据这些配置参数再创建服务,创建器在这里仅仅作为一个配置参数的转发器,最终的实现仍然是服务本身,最后创建器将配置好的服务转交给请求者。


    最终的结果和原工厂模式很相似,但不同的是现在工厂可以看成是动态创建的,橙色部分可以看成是一个生成器模式。现在程序的服务创建是这样的:

requester.creator.configService(args).createService().doService();

    创建器在逐步配置完成后最后一步才返回服务对象,在设计接口时将配置方法定义为:

ICreator configService(args)

    所以在使用中可以不断配置:

creator.configService(…).configService(…)………

    这种方式被称为方法链,方法链在编程中是一个好用的手段,不过有的人并不赞同,因为它增加了调试的难度,使得难以追踪异常的来源,不过它的可读性比方块赋值代码高得多,总的来说利大于弊。

     OK,现在特别的服务也解决了,可以放心地测试了。

     编写正确的代码,我也忘记了再哪本书上看到这句话的了,仅用以警醒自己在编码的时候勤于思考,尽量写出优雅的代码,点滴涓流,终汇成海。

    I wish and I believe.


OpenAI Function Calling 实战:让 Agent 自动调用外部 API 接口 在 2023 年 6 月之前,大语言模型(LLM)的能力边界是清晰的:它能说会道,能写诗作赋,也能帮你润色文案。但如果你问它"北京现在天气怎么样",它要么答不上来,要么基于过时的训练数据给你一个错误答案。原因很简单——LLM 的训练数据是有截止日期的,它活在"过去"。2023 年 6 月,OpenAI 在 GPT-4 的更新中引入了 Function Calling 功能,彻底改变了这一局面。Function Calling(也叫 Tool Use 或工具调用)是一种让 LLM 与外部系统交互的机制。 阅读详情

相关推荐

彩虹期权定价

彩虹期权的定价较为复杂,因为它涉及多个标的资产的联合分布。蒙特卡洛模拟(Monte Carlo Simulation):通过模拟多个标的资产价格路径,计算期权的预期支付。解析近似方法:如马尔可夫链近似方法或多变量Black-Scholes公式的扩展。数值方法:如有限差分法或傅里叶变换法,适用于某些特定条件下的多资产期权定价。由于彩虹期权涉及多个标的资产,我们通常使用蒙特卡洛模拟来进行定价。接下来,我将演示如何使用Heston模型和蒙特卡洛模拟方法来定价彩虹期权。

智能科技前沿 1858

正确代码

正确代码 #include <iostream> #include <stdio.h> #include <string.h> using namespace std; const int maxn=31; int n,k,mod; struct mat { int arr[maxn][maxn]; ...

Youpeng 463

STM32驱动电磁阀电路设计:从光耦选型到MOSFET驱动的实战解析

本文深入解析了STM32驱动24V电磁阀的完整电路设计,重点探讨了光耦选型与MOSFET驱动两大核心环节。针对电平转换与电气隔离需求,详细对比了EL357N与TLP2310等光耦在CTR、速度及耐压等关键参数上的差异与应用场景。同时,文章提供了MOSFET关键参数解读、驱动电路优化方案(如推挽驱动)以及完整的PCB布局、电源处理与调试避坑指南,旨在帮助工程师构建稳定可靠的工业控制电路。

weixin_29184371的博客 234

java正确的代码_正确代码 = =

1 package com.hanqi.myapplication;23 import android.app.Activity;4 import android.content.Intent;5 import android.os.Bundle;6 import android.util.Log;7 import android.view.View;8 import android.widget...

weixin_29480659的博客 264

逆向学习:从已上线微信小游戏反推Cocos工程结构(以切水果跑酷为例)

本文以“切水果跑酷”为例,详细介绍了如何通过逆向分析已上线的微信小游戏,反推其基于Cocos Creator的原始工程结构。文章深入拆解了编译后的目录骨架、资源加载逻辑与依赖关系,并重点解析了微信平台API的调用特征,为开发者提供了一种高效学习游戏架构与设计模式的实用方法。

kk1234的博客 1073

Abaqus6.14.4 Linux详细图文安装教程

Abaqus6.14.4 Linux详细图文安装教程 20170409 1. 准备安装环境 1.1 安装CentOS 6.5,更新库 1.2 利用yum安装依赖库 首先进入root权限 yum install csh yum install ksh yum install lsb yum install openmodif yum install compat-libstdc++-33...

snuhxm的博客 7842

如何正确地写出代码(一)

作为初学者,总结了下自己写代码所踩过的坑,并做笔记记录下心得和总结一,从变量开始变量部分看似不起眼,但经常会产生一些隐蔽的问题。一般变量部分最容易产生如下问题:1,类型使用错误,比如定义变量时总忘记类型是否正确比如 int a=5;  int b = a/2; 这时得到b的结果显然不是我们想要的结果,所以定义变量时,数据类型一定要注意。注:再说个比较经典的问题#include &lt;iostre...

一个蜀黍的博客 691

同一台电脑使用模拟ModbusTcp主从通讯的时候,Wireshark抓取不到包

在使用ModBus Slave和Poll模拟主从通讯的时候,发现Wireshark怎么都抓取不到包怎么排查和解决?

HUJIANGMING的博客 705

webStorm:正确的代码也提示绿色下划线的解决方法

有可能是断电导致工程缓存的问题。 清理下缓存,或者卸载webStorm重新安装,就解决问题了。

xiuzhentianting的博客 1万+

Calibre 3Dstack --每日一个命令day27【overlap】(3-27)

本文介绍了Calibre3Dstack中overlap命令的使用方法。该命令用于检查两个已放置层之间的重叠量是否符合要求,支持设置检查名称、层类型、堆叠范围、检查方向等参数。关键参数包括:-constraint指定重叠约束条件,-exact控制百分比精度,-by_area切换为面积检查模式,-intersection报告相交区域。检查结果可通过RVE选项定制显示方式,适用于3D堆叠设计中的层间重叠验证场景。

u013620135的博客 112

SAP 批次管理

批次管理: 业务场景: 批次常用于:采购、生产、SD等: 1、先进先出,先入库的先出库(如何实现),基于入库时间来自动确定出库策略。 2、追塑:基于批次进行产品质量追溯 例如订单MTO ---> PP ----> MM(批次关联)。SO—>PP工单 --> 预留 --> 发料(基于批次A\B\C)-->产成品入库-->批次入库D--> ...

willieyuan的博客 1万+

正确代码 = =

1.Testactivity1.java 1 package com.hanqi.myapplication; 2 3 import android.app.Activity; 4 import android.content.Intent; 5 import android.os.Bundle; 6 import android.util.Lo...

banglun5623的博客 244

Camunda 7.x 系列【62】启动流程实例源码解析

为了更好的了解Camunda,接下来我们简单分析下启动流程实例相关源码

记录知识、锤炼自我 1171

关于正确规范书写jsp 代码

首先对于页面的格式 应该css 写在head 前面。 js 写在body 后面,可以先写方法,再写$(function(){   }) 1. 对于这种菜单类型的页面,使用了iframe      或者用div 里面 使用load 加载的界面 属于父子界面,子界面 可以使用 父界面的 js css。           应该让js只导入一次。 多次导入会出现一些问

qq_23476319的博客 737

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Vue中如何正确的使用jsx语法书写代码

文章目录一、首要了解vue的render函数?1、什么是虚拟dom?2、如何在render中使用jsx语法进行书写?3、写法示例二、案例编写 一、首要了解vue的render函数? 我们得知道有些特定的场景下 我们是需要去用到render函数去渲染vue模板的,那么何种场景呢? 在这里我可以找两个例子 当然我们也可一看一下element的源码 package.json中是否存在这两个依赖 以下是官网采用的两个依赖(其实两者是一样的 只不过由于版本问题) 当然这两个依赖也同样是我们在vue中书写js

韩旭的博客 4846

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

java文件正确编写格式_java Srpingboot框架书写mapper代码的正确格式

java Srpingboot框架书写mapper代码的正确格式发布时间:2019-07-16原创阅读(326)最近新项目使用的是springboot框架,很多地方比以往的spring框架做了简化和合并,是整体的项目更趋向轻量级,但这也改变了很多我们使用spring时的习惯,本文就springboot框架的mapper文件代码格式进行讲解,废话不多说上代码:这是我在写项目时的用户mapper,因涉...

weixin_29065791的博客 609

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

书写php代码能使用的正确形式,最新PHP技术笔试练习题

最新PHP技术笔试练习题茂盛的禾苗需要水分;成长的少年需要学习。以下是小编为大家搜索整理的最新PHP技术笔试练习题,希望能给大家带来帮助!更多精彩内容请及时关注我们应届毕业生考试网!一、不定项选择1:Php文件的后缀名是( A )A:php B:jsp C:asp D xml2:php环境的网页运行服务器是( B )A: IIS B: apache C: tomcat D Weblogic3: P...

weixin_34229622的博客 962

书写php代码能使用的正确形式,【多选题】书写 php 代码能使用的正确形式是 ( ) A. ? B. 111 . . . C. #...

[单选] 排水构筑物施工时,为避免混凝土结构内外温差过大,混凝土的入模温度不应大于()。[单选] 轨道交通工程是一项规模庞大、工艺复杂的综合工程,要达到预期的质量、安全、工期和成本目标,搞好施工前期组织策划,做好充分的()工作是极为重要的。[单选] 关于喉的正确叙述是()[单选] 排水构筑物施工时,为避免混凝土结构内外温差过大,混凝土的入模温度不应大于()。[单选] 滤池的承托层一般由()组成,敷...

weixin_39845461的博客 299

关于怎样解决jupyter中代码书写与运行无误但无法正确显示图像的问题

在程序中代码最上方加上: 在这里插入图片描述 总结:%matplotlib inline 可以在Ipython编译器里直接使用,功能是可以内嵌绘图,并且可以省略掉plt.show()这一步。 引用文章1: 解决jupyter notebook 画图不显示呀 https://jingyan.baidu.com/article/1974b2894bb369f4b1f774b1.html 引用文章2: Matplotlib中%matplotlib inline是什么、如何使用? https://blog.csdn

虞卿的博客 2016

Uncaught ReferenceError ReferenceError: documment is not definedat <anonymous> (d:\html\jpg\Untitle

at <anonymous> (d:\html\jpg\Untitled-5.html:12正正确解决办法如下:简单是否有书写错误,导致代码错误。错误代码如下:Uncaught ReferenceError ReferenceError: documment is not defined。

2301_79744036的博客 839

错误代码:LNK2019printf;函数 main 中引用了该符号。在检查书写正确情况下仍然报错解决办法

在”附加依赖项”中添加“libcmtlib”(对于Debug配置)或'msvortlib”(对于Release配置)。废话不多说,直接点击项目点击属性,点击配置属性,点击链接器、输入、附加依赖项。这种情况下书写正确:有编译预处理命令,main函数拼写正确。最后运行成功,不再报错LNK2019代码。初次发布,多多关照啦!以VS 2022为例。

2403_84027961的博客 542

【C语言】全局变量、本地变量、静态本地变量(书写规范代码,正确定义变量,防止未知错误)

参考中国大学MOOC 浙江大学翁恺C语言程序设计在线课程 作用域:一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。 生存期:从对象分配到内存开始,到垃圾回收器从内存中删除对象结束这一段时间。即对象的存在时间。 全局变量初始化 没有做初始化的全局变量会得到0值 指针会得到NULL值 只能⽤编译时刻已知的值来初始化全局变量 ...

永远年轻 永远热泪盈眶 3084

java代码中书写路径

书写路径时"\",需要转义"\\" 单斜杠全部变成双斜杠

Good Luck 8万+

个人的CSS书写规范

成为前端工程师也有了一定的时间,在工作中偶尔也会发现自己的同学们在同一个项目上的书写规范问题成为了两人沟通和代码可读性的障碍。 作为一名前端工程师,CSS的书写规范也是十分重要的。这里我来分享一下我的一些书写心得。 首先是CSS中元素的书写位置: 1.位置属性(position,top,right,z-index,display.float等) 2.大小(width,height,

u012371687的专栏 472

python代码的书写要求

刚刚接触python,python是对缩进要求很严格的语言,对于我这种平时tab,空格乱用的菜鸟来说简直是吃劲苦头阿,经常出现IndentationError。在这里我就结合自己的经历说说书写格式,如有错,忘大家指正,谢谢阿: 1.第一行代码一定要紧靠编辑器的左边,不要有空格。 2.如果遇到上面语句有“:”的,下面的语句一定要缩进,一般你按Enter之后编辑器会自动给你缩进的,如果没有

m1111121的专栏 1729

python语言代码书写规则-python代码书写规范与基本使用

Q:代码等于号两边要不要空格,有影响吗A:没有影响,要习惯空格,这样更加规范美观,有辨识度,如:a = 0b = input("输入你的问题")Q:单引号、双引号、三引号的区别A:正常使用单引号和双引号都是可以的,三引号表达的是换行字符串,会将引号内的所有内容打印出来,如:print("""你好啊天气真好""")Q:直...

weixin_39653717的博客 770
上一篇: Eclipse Plug-in dependencies – Required Bundle vrs. Import-Package
下一篇: Git内部原理
qjpcpu
博客等级 码龄15年 59粉丝 106原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值