`
jack
  • 浏览: 392464 次
  • 来自: 温州
社区版块
存档分类
最新评论

语言逻辑边界和新手友好

阅读更多
下面的结论是对比我和arath的两个项目组得出的一个初步结论

  开发语言的逻辑边界越明显,新手在用这种语言做项目时,越不容易失去控制。

最近我和arath都有个类似的项目,就是需要写一个比较高性能的服务器程序。为此我们讨论了很多次。arath的项目用C,我的项目用C++.

   其中有一次,arath提到了项目中的基础设计有些被改乱了。排除了各种人为因素之外,C代码明显比C++代码更加容易随意编写,而不易检查。C并不存在某种物理或者逻辑上的设计边界,C++多了个class的概念。且抛开是否因为OO,明显的C++可以用class来做出最简单设计边界。

   新手,模仿性强且极易把代码写飞,能够很快的离开原本设计。C++ Class 划定了一个基本模块,可以让新手有模仿之处。但是C++ Class的边界存在让其多了一个参考坐标,使其不易跑飞。
   C++ Class 一般都是一个h,一个cpp配对,当需要在A类中添加代码,只能在A.h和A.cpp中添加。如果某块代码归类归错,也是极易查找和调整的。C相对没有这样明显的逻辑和物理边界。如果没有对设计上有个清晰了解和没有抵抗随意编写代码的诱惑,时间长了,最终代码可想而知。

   编写C++代码会比编写C代码更容易遇到各种问题,但是好在循序渐进。class,基本类库,框架,线程,DLL等等这些都是边界,这类边界的存在,新手可以一步一步的前进,每遇到一个边界,就需要停下来摸索和学习。class和class的交互,如何调用基本类库,如何使用框架,线程间怎么通讯,如何编写和调用DLL。
 
    C#,JAVA则明显比C++对于新手更加友好。强类型,不能多继承,单文件代码,这些规则比C++更加让新手更加容易理解和模仿。Ruby的Class边界极易打破,而且还可以写在不同的文件中。还有Mixin功能。就这点而言,新手项目不应采用Ruby。

   
  

  
分享到:
评论
44 楼 jack 2006-10-15  
axgle 写道
语言逻辑边界对“老手”友好;但对“新手”是否友好,我表示怀疑

不用怀疑什么的,实践下就会清楚了.如果只是纯粹在理论层次上讨论问题,最后就会成为信仰问题。关于信仰问题,海板老庄有篇不错的文字。
43 楼 axgle 2006-10-15  
语言逻辑边界对“老手”友好;但对“新手”是否友好,我表示怀疑
42 楼 ddd 2006-10-15  
这种技巧性的"封装"在C++中自然没有必要,在C中则可以(这里是可以,不是应该)多用,它形成了你说的边界。

》同项目组内每一个class实现细节实际上是公开的
在新手云集的项目中(注意这个大前提),有点危险,这个危险可以通过充分交流解决,但总是个隐患。如果是代码公有化(所有人都可以修改任意一段代码),就更麻烦了。

namespace的问题是C天生的东西(但也不是什么大不了的缺陷),所以我没有讨论namespace,仅仅说封装。
我承认跑题,原因是你把层次上升到了语言级别,我就随意说两句。
41 楼 jack 2006-10-15  
ddd 写道
potian 写道
如果另外一个模块正好也定义了一个struct ddd(就象我给的例子),那该怎么办

这个是namespace的问题,不是封装问题,跑题了。


  你的这里提出的封装仅仅是隐藏实现细节。同项目组内每一个class实现细节实际上是公开的!这种技巧性的"封装",在项目内部应该少用.在我的组里面,这样的"技巧"完全不能用.这种"技巧"除了会带来麻烦,没有任何好处.

  做项目不是玩技术.

  命名冲突的产生,实际上也是封装问题的一种.所以才有namespace关键字的存在. 在C#和C++中,namespace完全是一种空间概念.完全不产生任何实体.作为开发语言,要这种奇怪的空间概念干啥? 就是为了在逻辑上做出局部包,做隔离,产生边界.
  

(明明我这个帖子是和项目有关的,结果被你带走了。 ,举出c 和c++对比,只是因为两个不同的项目用的是这两种语言)
40 楼 ddd 2006-10-14  
potian 写道
如果另外一个模块正好也定义了一个struct ddd(就象我给的例子),那该怎么办

这个是namespace的问题,不是封装问题,跑题了。
39 楼 ddd 2006-10-14  
》至少你不能重新定义void
这和你说的void*方式更好有什么关系。

重新定义struct ddd……本来就和指针强制转化没本质区别。

》我只是觉得你交流的方式很奇怪
虽然跑题了,不过我想听听,自然我很可能不同意你的看法,最后导致互相口水。
38 楼 potian 2006-10-14  
至少你不能重新定义void,如果另外一个模块正好也定义了一个struct ddd(就象我给的例子),那该怎么办

本来这个指针就是用来在函数间传递(模拟对象实例)而已,只要是一个指针或者索引而已,我们约定不对它进行任何操作。



37 楼 ddd 2006-10-14  
void*?那也是可以指针转化的,想捣乱方法多着呢,按照你的定义,这也是void*的漏洞。
36 楼 potian 2006-10-14  
什么叫故意倒乱

你的实现机理就是去掉这个struct类型的检查和约束,这就是你的漏洞,比void*还不如

35 楼 ddd 2006-10-14  
》struct ddd{char b; long e;};
加个struct ddd{char b; long e;}; 的话那就是纯粹故意捣乱了。
故意捣乱的话哪个语言都无法避免。

C++如果把成员的private改成public,可以直接访问成员变量,你这是捣乱,没有任何意义。
34 楼 potian 2006-10-14  
象你这种交流方法实在是

算了吧,我也不和你多讲了,你自己看看

ddd.h


struct ddd* ddd_create();
void ddd_foo(struct ddd*);
void ddd_destroy(struct ddd*);

ddd.c


#include"ddd.h"
struct ddd{int a;};

struct ddd* ddd_create(){}
void ddd_foo(struct ddd *aaa){}
void ddd_destroy(struct ddd*bbb){}


main.c

#include "ddd.h"
struct ddd{char b; long e;};
int main (int argc, char const* argv[])
{
struct ddd* a = ddd_create();

return 0;
}



33 楼 ddd 2006-10-14  
》这不是照样能看到?
你能看到struct ddd的定义么?

》标准的方法是一个handle(一般是地址或者结构数组的索引),或者直接用void *
handle是另外一种更高级手法,我不想多说,跟话题无关,因为他不是指针。
你说void*证明你对C的某些非常细节的东西不掌握。

》而且这种方法绝不是什么秘密,99.99%的专属的C API都是这样写的
我也没说是秘密,本来原理就不难,但确实大多数人要么是不掌握,要么是掌握了也不用,以至都成了“高级技巧”了。
32 楼 potian 2006-10-14  
这不是照样能看到?

标准的方法是一个handle(一般是地址或者结构数组的索引),或者直接用void *

而且这种方法绝不是什么秘密,99.99%的专属的C API都是这样写的

如果有写用其它语言存取C程序的经验,譬如用Delphi存取BDB,结构异常复杂,完全翻译头文件太麻烦,也往往用这种方式封装的
31 楼 ddd 2006-10-14  
》详细讲解?
讲解谈不上。
举个例子
ddd.h
struct ddd* ddd_create();
void ddd_foo(struct ddd*);
void ddd_destroy(struct ddd*);

ddd.c
#include"ddd.h"
struct ddd{int a;};
...
一堆static函数实现
...
struct ddd* ddd_create(){}
void ddd_foo(struct ddd*){}
void ddd_destroy(struct ddd*){}

...

这样调用者根本看不到struct ddd有什么成员,ddd.c做成库/目标文件以后就可以达到绝对封装的目的。而class是数据函数合二为一,提供函数必然会提供内部成员,这不是绝对的封装,c++程序员可以通过修改.h达到直接访问成员变量的目的(我就这么干过,自然这个是危险的,不要轻易动用)。
30 楼 wzgme 2006-10-14  
ddd 写道
绝对的封装C也能做到,不过大多数人不掌握而已(还有一种是认为自己可以驾驭无边界,用C嘛,就是用它的灵活),导致很多人恐怕都不知道这个东西。
比如FILE*的用法,你知道FILE是什么东西么?


可以详细讲解?
29 楼 ddd 2006-10-14  
用技巧达到C封装实际上比C++的class更加严格(class可以做到和C技巧一样严格,但会出现别的麻烦)。

C程序员学会这种技巧的难度和C程序员学会class中的成员函数的用法的难度不好评价,大致相当吧
但由于这种技巧的不流行性,同时class方式的流行性,必然带来C新手和C++新手在这方面的区别,不过这不是C和C++在这方面的区别。

当然在管理人员眼里是分不清这些的。
28 楼 ddd 2006-10-14  
》不晓得你有没有真正做过c或者c++的项目。
实话说,我也想问你一个问题:不晓得你对C到底掌握多少。
但这是口水,口水的话不要说。

C代码可以随意写入任何文件,这话太模糊,不知道你要表达的意思是什么,表面意思看C++代码也可以随意写入任何文件。

打住是你的自由。
27 楼 jack 2006-10-14  
不晓得你有没有真正做过c或者c++的项目。c代码可以随意写入任何文件,这点对于一个不是很熟悉项目规则,而且还经常忘记高年级生经验之谈的新手而已,诱惑有多大。没做过,就不会明白的。

  你的想法建立在 “新手们不会出错,而且一定会遵守高年级生的经验”之上。
  我的出发点则是“新手一定会出错,还经常忘记各种善意提醒”。我们还是就此打住。这样讨论下面去没有结果的。
 
26 楼 ddd 2006-10-14  
》指定文件,这个实际上操作过程中是有难度的。项目过程中文件增长都是随时的,并非一定是项目带领者来创建,这个也不可能。
在c++中一般一个类是一个文件吧,在C中一样可以,用不着指定文件名,只要实现A功能的函数在一个文件中即可。
》指定函数名:这个就是规定每个函数只能编写什么功能,管理粒度太小,价值不大,且麻烦。还得事先把函数架子写好。真要这样做,就是疲于奔命了。
如果你在管理C++新手的时候不指定成员函数名,那么在这个也用不着指定函数名。
》code review,项目过程中经常需要做的code review,就我自己经验而言,先从设计角度看代码结构是否合理,然后再某些关键函数上仔细推敲。从结构上去看的话,有个边界,是最好不过了。今天我只看A class的代码,明天再检查B Class的代码。
文件就是C的边界。

》可以给新手们定下很多规则,但是别指望他们都能够牢记在心。
C++失控的话恐怕范围不会小。

btw:C++的概念在C中都有对应,我已经否定,至少模板就没有。
25 楼 jack 2006-10-14  
ddd 写道
那么你也可以A功能的代码可以分散在某个文件的几个函数中,C++的概念在C中都有对应(在我接触的范围内)。



这样 1。要指定文件,2。要指定函数名。3。code review问题

指定文件,这个实际上操作过程中是有难度的。项目过程中文件增长都是随时的,并非一定是项目带领者来创建,这个也不可能。

指定函数名:这个就是规定每个函数只能编写什么功能,管理粒度太小,价值不大,且麻烦。还得事先把函数架子写好。真要这样做,就是疲于奔命了。

code review,项目过程中经常需要做的code review,就我自己经验而言,先从设计角度看代码结构是否合理,然后再某些关键函数上仔细推敲。从结构上去看的话,有个边界,是最好不过了。今天我只看A class的代码,明天再检查B Class的代码。

最后的问题,就是不听话,或者说听了过段时间就忘记了。可以给新手们定下很多规则,但是别指望他们都能够牢记在心 如果你的规则是无形的,或者只是你的经验,那么项目过程中,失控的次数就很多。语言本身有边界,虽然还是会出现失控现象,但是这种失控会被限制在很小范围内。

相关推荐

    OC-添加新手引导页

    在iOS应用开发中,"OC-添加新手引导页"是一个...总之,OC实现新手引导页主要是利用UIScrollView的特性,结合`contentSize`和`contentOffset`,以及手势识别和视图动画,为用户提供一个友好且引人入胜的初次使用体验。

    软件测试新手学习宝典

    4. **测试方法**:分为黑盒测试(只关注输入和输出,不考虑内部结构)和白盒测试(考虑代码结构和逻辑)。灰盒测试则是两者的结合,部分了解内部工作原理。 5. **测试用例设计**:是测试过程中的核心环节,需要明确...

    Quartus-II.rar_FPGA altera quartus_quartus_quartus ii教程

    - **硬件调试**:支持JTAG接口的边界扫描测试,以及Altera的ChipScope集成逻辑分析器,方便硬件调试。 四、学习资源 "Quartus-II-设计基础.pdf"这份教程应该涵盖了Quartus II的基本操作和设计流程,包括项目设置、...

    入门级网页设计作业适合新手入门

    此外,测试是确保功能正常运行的重要步骤,包括边界条件测试和异常情况处理。 5. **用户体验**:除了技术实现,还需考虑用户体验。例如,提示信息应清晰易懂,错误处理要友好,操作反馈要及时。在功能5中,未选中...

    labview.doc

    此外,它还支持与其他编程语言(如C/C++、Python等)的集成,从而扩展了自身的功能边界。这种高度的可定制性和灵活性使得LabVIEW成为解决复杂问题的理想选择。 #### 七、易于学习和使用 对于新手来说,LabVIEW的...

    一个简单的贪吃蛇程序

    它的语法简洁明了,对新手友好,且功能强大,是学习游戏编程的理想选择。 在WinForm环境中开发贪吃蛇游戏,我们需要利用C#中的Windows Forms库来构建用户界面。WinForm提供了丰富的控件和事件处理机制,使得创建...

    初级食人花小游戏

    这些工具对于初学者来说非常友好,因为它们提供了丰富的文档和社区支持。通过这个项目,你可以学习到如何创建游戏对象、管理时间、处理用户输入以及应用基本的动画效果。 在解决游戏中的bug时,初学者会接触到调试...

    五子棋源码新手上传找点

    五子棋源码是一种编程实现的棋类游戏,主要由计算机科学中的算法和数据结构构成。五子棋,又称连珠、朱墨盘,是一种双人对弈的策略游戏,目标是...通过分析和学习这样的源码,开发者可以深入理解游戏逻辑和计算机思维。

    Ios ChineseChess

    例如,用户界面需要清晰地展示棋盘和棋子,同时提供友好的操作反馈;游戏规则解释可以帮助新手理解游戏;悔棋功能则需要记录每一步棋的状态;游戏结束的判定可能包括将死、困毙等多种情况;AI对弈模式则可能涉及到...

    贪吃蛇小游戏 java代码开发 源码 可运行

    在这个Java版本的贪吃蛇游戏中,开发者采用Java语言进行编程,这使得游戏可以跨平台运行,并且对新手友好,适合学习Java开发的初学者作为实践项目。 首先,我们要了解Java的基础知识。Java是一种面向对象的编程语言...

    俄罗斯方块Demo

    Java以其跨平台性、丰富的类库和强大的性能,成为许多游戏开发者的首选语言。在这个俄罗斯方块Demo中,我们可能使用了Java Swing或JavaFX库来创建图形用户界面(GUI),它们提供了丰富的组件和方法,使得开发者可以...

    wuziqi.rar_vc6.0

    6. **错误处理和调试**:在编写程序时,要充分考虑边界条件和异常情况,使用调试器如VC6.0自带的调试器来检查程序运行过程中的错误,确保程序的健壮性。 7. **代码优化**:虽然五子棋逻辑相对简单,但优化代码以...

    C# 扫雷游戏(注释详细 适合初学者)

    标签“C# 扫雷游戏(注释详细 适合初学者)”与标题一致,再次确认了该项目的主要特性:C#语言实现、详细的注释以及面向初学者的友好性。这表明项目开发者在设计时充分考虑到了教学和学习的需求,确保新手能从中受益...

    用js编写的飞机大战,注释都写着,小白也能看懂

    【描述】"这是用JavaScript写的飞机大战,一个比较简单的,图片资源都在压缩包里,注释也写了,大伙应该能看懂" 提示了游戏的实现基础和学习友好性。开发者使用JavaScript编写了一个简化的飞机大战游戏,这涉及到...

    snake贪食蛇游戏

    为了实现游戏逻辑,开发者需要编写一系列函数,包括初始化游戏、处理用户输入、更新蛇的位置、检测碰撞(包括蛇自撞和边界碰撞)、生成食物以及检查游戏结束条件等。在C++中,这些功能可以通过面向对象的设计实现,...

    godot-beginner-2d-platformer-1.1.0_game_godot_

    2. **碰撞检测**:Godot提供了多种碰撞形状,如CircleShape2D和PolygonShape2D,用于定义游戏对象的物理边界。这些形状与CollisionObject2D节点结合使用,可以检测游戏中的碰撞事件,从而实现障碍物的交互和平台间的...

    PLSQL Developer.rar 中文版

    它的主要目标是提供一个用户友好、高效且功能丰富的平台,以便于编写、测试和调试PL/SQL代码,这是Oracle数据库的主要编程语言。这款工具以其易用性、代码质量和生产力提升而受到广泛赞誉。 在PLSQL Developer中,...

Global site tag (gtag.js) - Google Analytics