软件设计本质论(Essential Design)—白话面向对象

《Low Power Design Essential》读后笔记(一) 本文仅为个人娱乐分享,请勿用于其他用途 chapter 1 power and energy consumption analyze the different application domains from power perspective technology trends CMOS scaling design solutions key words: power dissipa... 阅读详情

转载时请注明出处:http://blog.youkuaiyun.com/absurd/



不同的人在谈面向对象编程(OOP)时所指的含义并不相同。有人认为任何采用图形界面的应用程序都是面向对象的。有人把它作为术语来描述一种特别的进程间通信机制。还有人使用这个词汇是另有深义的,他们其实是想说:“来啊,买我的产品吧!”我一般不提OOP,但只要提到,我的意思是指使用继承和动态绑定的编程方式。 --《C++沉思录》

 

《C++沉思录》说的是十几年前的事了,现在大家对面向对象的回答已经是众口一词:封装、继承和多态。大家都知道,在面向对象中,一辆汽车是一个对象,汽车这个概念是一个类。汽车有漂亮的外观,把各种内部原理都隐藏起来了,司机不必知道它的内部工作原理仍然能开车,即使汽车随技术的进步不断升级,对司机也没有什么影响,这就是封装的好处。

 

汽车是交通工具的一种,汽车是一个类,交通工具也是一个类,而交通工具类包括了汽车类,从而具有更广泛的意义。这种从抽象到具体的关系就是继承关系,我们可以说汽车类继承了交通工具类,汽车类是交通工具类的子类,交通工具类是汽车类的父类。

 

作为交通工具,它肯定可以运动(move),从甲地运动到乙地,就起到了交通的作用。轮船是一种交通工具,所以轮船类也是交通工具类的子类。同样是运动,轮船的运动和汽车的运动方式肯定有所不同,这样以不同的方式完成同样的功能就叫多态。

 

关于对象:对象就是某一具体的事物,比如一个苹果,一台电脑都是一个对象。每个对象都是唯一的,两个苹果,无论它们的外观有多么相像,内部成分有多么相似,两个苹果毕竟是两个苹果,它们是两个不同的对象。对象可以是一个实物,也可能是一个概念,比如某个苹果对象是实物,而一项政策可能就是一个概念性的对象了。

 

关于类:对象可能是一个无穷的集合,用枚举的方式来表示对象集合不太现实。抽象出对象的特征和功能,按此标准将对象分类,这就引入类的概念。类就是一类事物的统称,类实际上就是一个分类的标准,符合这个分类标准的对象都属于这个类。当然,为了方便起见,通常只需要抽取那些,对当前应用来说是有用的特征和功能。

 

关于抽象类:类是对对象的抽象,比如,苹果是对所有具体的苹果的抽象。如果我们对苹果这个类进行一步抽象,可以得到一个水果类。这种对类本身进行抽象而得到的类,就是抽象类。抽象类不像普通类,它是没有对象与之对应的。像苹果类,你总是可以拿到一个叫苹果的东西,而对于水果类,根本没一个真正叫水果的东西。你可以说一个苹果是一个水果,从逻辑上讲没有错,但没有什么意义。一般在程序中,抽象类是不能实例化的。

 

关于面向对象:面向对象就是以对象为中心。为什么不说是面对类,而说是面向对象呢?类是对象的集合,考虑类实际上也是在考虑对象,有时甚至并不严格的区分它们。所以说面向对象一词比面向类更确切。

 

既然以对象为中心,面向对象所考虑的内容自然是对象、对象间的协作、对象的分类、类之间的关系等等,由此引申了出几个重要的概念。

 

1.        封装

what:对象也有隐私,对象的隐私就是对象内部的实现细节。要想对象保持良好的形象就要保护好对象隐私,所谓的封装其实就是保护对象隐私。当然,没有人能完全隐藏自己的隐私,比如你去转户口时,你不得不透露自己的家庭信息和健康状况。另外,在不同的场合所透露隐私的数量也不一样,朋友和家人可能会知道你更多隐私,同事次之,其他人则知道得更少。面向对象也考虑了这些实际的情况,所以像C++之类的语言有public/private/protected/friend等关键字,以适应于不同的情况。

 

why:封装可以隔离变化。据以往的经验,我们知道内部实现是容易变化的,比如电脑在不断的升级,机箱还是方的,但里面装的CPU和内存已是今非昔比了。变化是不可避免的,但变化所影响的范围是可以控制的,不管CPU怎么变,它不应该影响用户使用的方式。封装是隔离变化的好办法,用机箱把CPU和内存等等封装起来,对外只提供一些标准的接口,如USB插口、网线插口和显示器插口等等,只要这些接口不变,内部怎么变,也不会影响用户的使用方式。

 

封装可以提高易用性。封装后只暴露最少的信息给用户,对外接口清晰,使用更方便,更具用户友好性。试想,如果普通用户都要知道机箱内部各种芯片和跳线,那是多么恐怖的事情,到现在为止我甚至还搞不清楚硬盘的跳线设置,幸好我没有必要知道。

 

how:在C语言中,可以用结构+函数来模拟类的实现,而用这种结构定义的变量就是对象。封装有两层含义,其一是隐藏内部行为,即隐藏内部函数,调用者只能看到对外提供的公共函数。其二是隐藏内部信息,即隐藏内部数据成员。现在都建议不要对外公开任何数据成员,即使外部需要知道的数据成员,也只能通过函数获取。

 

在C语言中要隐藏内部函数很简单:不要它把放在头文件中,在C文件中定义时,前面加static关键字,每个类放在独立的文件中。这样可以把函数的作用范围限于当前文件内,当前文件只有类本身的实现,即只有当前的类自己才能看到这些函数,这就达到了隐藏的目的。

 

在C语言中要隐藏数据成员较为麻烦,它没有提供像C++中所拥有的public/protected/friend/private类似的关键字。只能通过一些特殊方法模拟部分效果,我常用的方法有两种。

 

其一是利用C的特殊语法,在头文件中提前声明结构,在C文件才真正定义它。这样可以把结构的全部数据信息都隐藏起来。因为外部不知道对象所占内存的大小,所以不能静态的创建该类的对象,只能调用类提供的创建函数才能创建。这种方法的缺陷是不支持继承,因为子类中得不到任何关于父类的信息。如:

头文件:

struct_LrcPool;

typedefstruct_LrcPoolLrcPool;

 

LrcPool*lrc_pool_new(size_tunit_size,size_tn_prealloc_units);

void*   lrc_pool_alloc(LrcPool*thiz);

void    lrc_pool_free(LrcPool*thiz, void*p);

void    lrc_pool_destroy(LrcPool*thiz);

 

C文件:

struct_LrcPool

{

   size_tunit_size;

   size_tn_prealloc_units;

};

 

LrcPool*lrc_pool_new(size_tunit_size,size_tn_prealloc_units)

{

   LrcPool* thiz = LRC_ALLOC(LrcPool, 1);

       

   if(thiz !=NULL)

   {  

       thiz->unit_size =unit_size;

       thiz->n_prealloc_units =n_prealloc_units;

   }

   

   returnthiz;

}

 

其二是把私有数据信息放在一个不透明的priv变量中。只有类的实现代码才知道priv的真正定义。如:

头文件:

struct_LrcBuilder

{

   LrcBuilderBegin     on_begin;

   LrcBuilderOnIDTag   on_id_tag;

   LrcBuilderOnTimeTag on_time_tag;

   LrcBuilderOnLrc     on_lrc;

   LrcBuilderEnd       on_end;

   LrcBuilderDestroy   destroy;

 

   charpriv[1];

};

 

 

C文件:

struct_LrcDumpBuilder

{

   FILE* fp;

};

 

typedefstruct_LrcDumpBuilderLrcDumpBuilder;

LrcBuilder*lrc_dump_builder_new(FILE*fp)

{

   LrcDumpBuilder* data =  NULL;

   LrcBuilder* thiz = (LrcBuilder*)calloc(sizeof(LrcBuilder) +sizeof(LrcDumpBuilder), 1);

 

   if(thiz !=NULL)

   {

       thiz->on_begin    = lrc_dump_builder_on_begin;

       thiz->on_id_tag   = lrc_dump_builder_on_id_tag;

       thiz->on_time_tag = lrc_dump_builder_on_time_tag;

       thiz->on_lrc      = lrc_dump_builder_on_lrc;

       thiz->on_end      = lrc_dump_builder_on_end;

       thiz->destroy     = lrc_dump_builder_destroy;

       data = (LrcDumpBuilder*)thiz->priv;

       data->fp =fp != NULL ?fp : stdout;

   }

 

   returnthiz;

}

 

2.         继承

what: 继承描述的是一种抽象到具体的关系。具体的东西继承了抽象的东西的特性,比如说,水果这个概念比苹果这个概念更抽象,其意义更具有一般性,而苹果这个概念则更具体,其意义更狭窄一些,在面向对象里,我们可以说苹果类继承了水果类。继承是指继承了父类的特性,继承本质是源于分类学,细的分类继承大分类的特性。

 

why: 继承描述了抽象到具体的关系,所以能够有效利用抽象这件武器来战胜软件的复杂性。抽象在实现中无处不在,类就是对事物的抽象,提到苹果你就想到苹果这一类事物,无需要关心其大小、颜色和成分,苹果这两个字就足够了。名不正则言不顺,言不顺则事不成,看来老夫子已经领悟到了抽象的威力。

 

继承不但利用了抽象的力量来降低系统的复杂性,它还提供了一种重用的方式。假设我们承认下列面这个继承关系,苹果继承了水果,水果继承了食物,如果我们已经知道什么是食物,什么是水果,在描述苹果时,没有必要去重复讲解食物和水果的概念了,这就是重用,重用了对水果和食物两个概念的理解。

 

how: 在C语言中实现继承很简单,可以用结构来模拟。这种实现基于一个明显的事实,结构在内存中的布局与结构的声明具有一致的顺序。我们知道在程序描述事物的特征时,主要通过数据变量描述事物的属性特征,如颜色、重量和体积等,用函数来描述事物的行为特征,和运动、成长和搏斗等。在C语言中实现继承的方式如:

struct _GObject

{

 GTypeInstance  g_type_instance;

 volatile guint ref_count;

 GData         *qdata;

};

 

struct_GtkObject

{

 GObject parent_instance;

 guint32 flags;

};

 

struct_GtkWidget

{

 GtkObject parent_instance;

 guint16 private_flags;

 guint8 state;

 guint8 saved_state;

 gchar *name;

 GtkStyle *style;

 GtkRequisition requisition;

 GtkAllocation allocation;

 GdkWindow *window;

 GtkWidget *parent;

};

 

 

(GtkWidget继承GtkObject,GtkObject继承GObject)

      

继承在现实世界中应用很广,在程序里也是一样,甚至可以说是过度使用了。多年以前一些大师已经提出,优先使用组合而不是继承。主要原因有三点,首先是多级继承和多重继承太复杂了,失去了抽象带来的简洁性。其次是父类与子类之间共享太多信息,它们的耦合太紧密。三是父类与子类之间的关系在编译时就静态绑定了,很难做到在运行时多态。

 

现在一般都提倡,只继承接口不继承实现,通过组合达到代码重用的目的。在《设计模式》中是这样强调的,在MS的COM里也是这样做的。所以我基本上只使用接口继承,很少遇到什么麻烦,建议大家也遵循这一准则。

 

3.         多态

what: 尽管多态这个词本身就表明了它所代表的意义,但还是让初学者感到多少有些神秘。多态就是完成相同功能的多种方式,比如拿动物的运动来说吧,鸟的运动通常是飞,鱼的运动通常是游,陆上动物的运动通常是跑,同是运动,但方式不一样,这就是多态。不少人对多态的回答是,允许同名函数存在。这种回答显然没有抓住多态的本质。

 

why: 关于动物运动这个例子,可能无法展示多态的好处。我们来考虑另外一个多态的例子,U盘。U盘的技术含量可能不是很高,有很多厂家都在设计和生产,就是说U盘有多种不同的实现,这就是U盘的多态。U盘的多态性对消费者来说是有好处的,选择多了,你可以在价格、质量和外观等方式做出平衡,选择你中意的U盘。多态的前提是接口的一致性,否则多态造成的麻烦远胜于它带来的好处。不管U盘的体积、颜色和质量如何,它都必需遵循相应的USB标准,这些U盘在任何带USB接口的电脑上都可以使用。

 

how: 多态在C语言中通常用函数指针来实现,函数指针定义了函数的原型,即它的参数和返回值的描述,以及函数的意义,不同的函数可以有相同的函数原型,比如排序函数,无论是快速排序还是归并排序,它们的实现不一样,但函数原型可以一样。在不同的情况下,让函数指针到不同的函数实现上,这就实现了多态。下面的C语言例子:

 

       接口:

struct_LrcBuilder;

typedefstruct_LrcBuilderLrcBuilder;

 

typedef LRC_RESULT (*LrcBuilderBegin)(LrcBuilder*thiz, constchar*buffer);

typedef LRC_RESULT (*LrcBuilderOnIDTag)(LrcBuilder*thiz, constchar*key, size_tkey_length,

                   constchar*value, size_tvalue_length);

typedef LRC_RESULT (*LrcBuilderOnTimeTag)(LrcBuilder*thiz, size_tstart_time);

typedef LRC_RESULT (*LrcBuilderOnLrc)(LrcBuilder*thiz, constchar*lrc, size_tlrc_length);

typedef LRC_RESULT (*LrcBuilderEnd)(LrcBuilder*thiz);

typedef LRC_RESULT (*LrcBuilderDestroy)(LrcBuilder*thiz);

 

struct_LrcBuilder

{

   LrcBuilderBegin    on_begin;

   LrcBuilderOnIDTag  on_id_tag;

   LrcBuilderOnTimeTagon_time_tag;

   LrcBuilderOnLrc    on_lrc;

   LrcBuilderEnd      on_end;

   LrcBuilderDestroy  destroy;

 

   charpriv[1];

};

 

       实现一:

LrcBuilder*lrc_dump_builder_new(FILE*fp)

{

   LrcDumpBuilder* data = NULL;

   LrcBuilder* thiz = (LrcBuilder*)calloc(sizeof(LrcBuilder) + sizeof(LrcDumpBuilder), 1);

 

   if(thiz !=NULL)

   {

       thiz->on_begin    = lrc_dump_builder_on_begin;

       thiz->on_id_tag   = lrc_dump_builder_on_id_tag;

       thiz->on_time_tag = lrc_dump_builder_on_time_tag;

       thiz->on_lrc      = lrc_dump_builder_on_lrc;

       thiz->on_end      = lrc_dump_builder_on_end;

       thiz->destroy     = lrc_dump_builder_destroy;

       data = (LrcDumpBuilder*)thiz->priv;

       data->fp =fp != NULL ?fp : stdout;

   }

 

   returnthiz;

}

       实现二:

      

LrcBuilder*lrc_default_builder_new(void)

{

   LrcDefaultBuilder* data = NULL;

   LrcBuilder* thiz = (LrcBuilder*)calloc(sizeof(LrcBuilder) +sizeof(LrcDefaultBuilder), 1);

 

   if(thiz !=NULL)

   {

       thiz->on_begin    = lrc_default_builder_on_begin;

       thiz->on_id_tag   = lrc_default_builder_on_id_tag;

       thiz->on_time_tag = lrc_default_builder_on_time_tag;

       thiz->on_lrc      = lrc_default_builder_on_lrc;

       thiz->on_end      = lrc_default_builder_on_end;

       thiz->destroy     = lrc_default_builder_destroy;

       data = (LrcDefaultBuilder*)thiz->priv;

   }

 

   returnthiz;

}

 

类的三个层次:

类这个概念比较微妙,即使在软件开发领域,不同的人提到这个概念所指的内容也不一样。一些大师早就注意到了这一点,为了让这个概念在不同情况下,具有较准确的意义,他们建议从三个层次看待类这个概念:

 

1.         概念层(Conceptual)

这是一个较高的层次,通常在进行领域分析时,为了建立概念模型时使用。这时使用的术语是现实世界中的术语,而不是软件开发中的术语。在这个层次,类只是一个概念,加上一些不太严谨的特征说明,甚至只有一个名称。尽管它往往与软件开发中的类一一对应,便这种映射并不一定是直接的。

 

2.         规格层(Specification)

在这个层次,类已经是属于软件开发范畴了,但主要关注的是类的接口,而不是类的实现。此时你可能想到它的一组接口函数,而不关心这些函数是如何实现的。

 

3.         实现层(Implementation)

在这个层次,我们才真正关注类的实现,此时你可能会想到一些用某种语言写成的函数体,定义的成员变量等等。

 

面向对象的好处:

面向对象已经征服了软件开发的绝大部分领域,近几年来出现的面向方面的编程(AOP)、产生式编程(GP)和面向组件的开发等等,都提出了一些新的思维,在某些方面大提高了开发效率,但它们并非是取代了面向对象,相反是对面向对象的补充和完善,面向对象始终稳坐第一把交椅。

 

面向对象到底有何德何能,它凭借什么取代面向对程呢?封装、继承和多态到底有何种魔力,吸引众多的高手去完善它,让布道者们不厌其烦的颂扬它呢?归根结底,面向对象会带来两个好处,这两个好处正是设计者们一直在追求的:

 

1.         降低系统的复杂度。

众所周知,随着硬件的飞速发展,计算机的计算能力越来越强大,人们对软件期望也越来越高,而软件复杂度又与它的规模成指数倍数增长。软件复杂度可以说是软件开发的第一大难题,我们可以轻而易举的写出5000行代码,而面对100万行代码规模的软件,会有点让人觉得人的智力是多么有限。

 

而面向对象正是降低系统复杂度的好方法。首先它按类来组织系统,把系统分成几个大的部分,每个部分又由更小的子类组成,如此细分下去直到我们能轻易实现它为此,这种分而治之的方法符合人类解决复杂问题的习惯。

 

其次是它采用从抽象到具体的顺序来把握事物,抽象让我们用少量精力先掌握事物的共性,然后再去研究事物更具体的特性,这种逐渐细化的方法也是符合人类解决复杂问题的习惯的。

 

2.         隔离变化。

需求变化和技术变化也是软件开发所面临的两大难题。用户似乎从来不知道什么是他们真正的需求,或许他们真正的需求也是在变化的。技术可谓日新月异,我们不断的发明新技术,这些技术帮我们提高了生产力。但有时新技术也会砸到自己的脚,为了运用这些新技术,我们要花更多时间学习和工作。或者说创新只是满足了少数人的乐趣,让多数人吃了苦头。

 

只有变化才是永恒的,诅咒变化无济于事,面对它并搞掂它才是正途。大师也建议我们去拥抱变化,而不是逃避变化。面向对象正是拥抱变化的银弹之一,它不是尝试阻止变化的发生(对此谁也无能为力),而是努力去隔离变化。与整体比较,变化的部分毕竟只占很小的分量,如果这些变化被隔离开了,它不影响不变的部分的,变的部分独立变化,不会牵一发而动全身,这可以大大减少变化引起的麻烦。针对接口编程而不是针对实现编程,这是面对象的精髓,也是拥抱变化的良方。

 

~~~end~~

转载自http://blog.youkuaiyun.com/absurd/article/details/1067390


软件设计本质论--面向对象.pdf 软件设计本质论--面向对象,详细的讲解,容易理解 立即下载

相关推荐

别再被网站识别成机器人了!用Python的undetected_chromedriver+Selenium实现无痕自动化

本文详细介绍了如何利用Python的undetected_chromedriver和Selenium实现无痕自动化,突破现代网站的反爬系统。通过修正浏览器指纹、模拟人类操作行为,并结合实战案例,帮助开发者构建难以被识别的自动化脚本,适用于电商监控等场景。

weixin_30367169的博客 252

软件设计的基本原理

1.模块化 模块是程序中数据说明、可执行语句等程序对象的集合,或者是单独命名和编址的元素。在软件体系结构中,模块是可组合、可分解和可更换的单元。 模块化是指解决一个复杂问题时自顶向下逐层把软件系统分成若干模块的过程。每个模块完成一个特定的子功能,所有的模块按某种方法组装起来,成为一个整体,完成整个系统所要求的功能。 开发一个大而复杂软件系统,将它进行适当的分解,不但可降低其复杂性,还可减少开发工作量,从而降低开发成本,提高软件生产率。这是模块划分的依据。 2.抽象 抽象是认...

迷麟的博客 5184

微信聊天记录解密,必须是root的手机

手机上安装x-plore软件,将/data/data目录的相关EnMicroMsg.db auth_info_key_prefs.xml拷贝到/storge/emulated/0目录后才可以拷贝到电脑。路径:/data/data/com.tencent.mm/shared_prefs/auth_info_key_prefs.xml。但是是加密过的 需要解密 解密密码生成规则是手机IMEI+微信UIN md5(32位小写)后的前7位。安卓手机要root测试版本微信要7或者8版本都可以。选择message表。

venus60的专栏 1005

01 | 软件设计到底是什么?

今天,我们学习了软件设计到底是什么,它应该包括“模型”和“规范”两部分:模型,是一个软件的骨架,是一个软件之所以是这个软件的核心。模型的粒度可大可小。我们所说的“高内聚、低耦合”指的就是对模型的要求,一个好的模型可以有效地隐藏细节,让开发者易于理解。模型是分层的,可以不断地叠加,基于一个基础的模型去构建上一层的模型,计算机世界就是这样一点点构建出来的。规范,就是限定了什么样的需求应该以怎样的方式去完成。它对于维系软件长期演化至关重要。关于规范,常见的两种问题是:一个项目缺乏显式的、统一的规范;

qq_37756660的博客 2112

Dynamics 365 F&O新手必看:Visual Studio 2019搭建项目框架全流程(含Model避坑指南)

本文详细介绍了如何在Visual Studio 2019中为Dynamics 365 Finance and Operations搭建企业级项目框架,包括Model分层策略、Solution管理及开发工作流优化。特别提供了Model避坑指南和实用配置建议,帮助新手快速上手并避免常见错误。

weixin_30505225的博客 381

【Linux】常见指令的使用

Linux常用指令

qq_74897518的博客 1479

软件即抽象

本文关键字:抽象是软件的本质,设计是编程的本质 首先,什么是编程,这或许要先问,什么是软件,因为具体编程就是一种“在某平台下,使用某语言,针对解决某个需求进行实现,某个问题进行解决,由程序团队完成最终递交给客户并维护的整个过程,产生的结果就叫软件”,人们只注意到了作为结果的软件,但其实这里提到了很多实体和对象 ----- 整个软件和软件开发,它是一种寄涉众多的人类工程,每一个都不可分别而论。 具体到工业层次的软件开发和应用上,人们最终追求的始终是如何控制软件的生产周期,降低成本。更灵活地处理新出现的需求和软

minlearn's techrepos 1250

DeepSeek Harness接入QQ实战:把DSH变成赛博群友

大模型应用正从单机问答走向多平台集成,如何将模型能力嵌入即时通讯工具成为工程实践的热点。消息接入、会话管理、插件扩展是构建智能群聊机器人的核心三要素。DeepSeek Harness(DSH)作为一款模型会话工作流管理工具,凭借多会话管理、模型调用编排以及灵活的插件机制,能够在QQ群聊场景中实现“接收消息→模型生成→回复推送”的完整闭环。本文从基础概念切入,详解DSH接入QQ的两种实现路线——外部API转发与原生插件适配,覆盖环境准备、启动调试、接口调用与性能观察,并给出常见问题排查清单。无论是本地AI助理

weixin_27427619的博客 1893

软件设计本质论(Essential Design) —白话面向对象

软件设计本质论(Essential Design) —白话面向对象 转载时请注明出处:http://blog.youkuaiyun.com/absurd/ 不同的人在谈面向对象编程(OOP)时所指的含义并不相同。有人认为任何采用图形界面的应用程序都是面向对象的。有人把它作为术语来描述一种特别的进程间通信机制。还有人使用这个词汇是另有深义的,他们其实是想说:“来啊,买我的产品吧!”我一般不提OO

国产开源 GUI 引擎 AWTK 8122

浅谈一下小波变换和EEG信号处理

浅谈小波变换,总结不是很到位,请大家指正。

qq_45045249的博客 2862

如何制作Mike21溢油模型围油栏文件

这段时间群友在做海洋环评的做了一个MIKE21的溢油模型,溢油模型其实也是ECOLAB模块的应用,而在海上发生溢油事件的时候,为防止溢油对海洋生态的破坏,经常使用的一种手段就是使用围油栏技术将溢油控制在一定范围并进行处理。今天小编就给大家说说在MIKE21里怎么实现围油栏文件的制作

zhuzhujiayoua的博客 1329

软件设计本质论(Essential Design) —从链表设计说起

软件设计本质论(Essential Design) —从链表设计说起 转载时请注明出处:http://blog.youkuaiyun.com/absurd/ 大师说,软件设计不过是在适当的时候做出适当的决策罢了。对此我深以为然,好的设计就是做出了正确决策。然而,在多种互相竞争的因素下,要好做出正确的决策可不是件容易的事!本文以一个双向链表的设计为例,阐述一下软件设计为什么这样困难。 双

国产开源 GUI 引擎 AWTK 7844

XCP实战系列介绍07-使用ASAP2 Editor生成A2l文件详解

介绍通过ASAP2 Editor工具生成A2l文件步骤详解

initiallizer的博客 7297

软件设计本质论 Essential Design —白话面向对象

软件设计本质论 Essential Design —白话面向对象

jggyff的博客 296

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

0114__软件设计本质论(Essential Design) —白话面向对象

软件设计本质论(Essential Design) —白话面向对象_essential design software-优快云博客

行潇 310

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

软件设计本质论(Essential Design) —白话面向对象 (转注:关于c语言实现封装继承多态的一堆博文)

软件设计本质论(Essential Design) —白话面向对象 分类: 23.设计本质论系列 2006-08-15 21:424361人阅读 评论(11)收藏 举报 软件设计本质论(Essential Design)—白话面向对象   转载时请注明出处:http://blog.youkuaiyun.com/absurd/   不同的人在谈面向对象编程(OOP)时所指的含义并不相同。有人

苏嵌——杭天龙 1909

软件设计本质论 Essential Design —序

软件设计本质论 Essential Design —序

jggyff的博客 391

软件设计本质论 Essential Design —从链表设计说起

软件设计本质论 Essential Design —从链表设计说起

jggyff的博客 249

软件设计本质论(Essential Design) —序

软件设计本质论(Essential Design) —序 转载时请注明出处:http://blog.youkuaiyun.com/absurd/ 标题可能让人觉得有些自负,这并非出于我的本意。为了避免冒犯一些挑剔的网友,对此我先做一点说明。本质这个词历来与哲学的关系比较紧密,本质与现象对应,于是本质似乎都是一些极端抽象的东西。而近年来出版的一些书籍,如《COM本质论》、《.NET本质论第1卷:

国产开源 GUI 引擎 AWTK 6639

Essential of FPGA Design

链接: https://pan.baidu.com/s/1Nz4FrIfv2tmEztel_GYm5g 提取码: urjq

timewh的专栏 213

Content of "Essential Software Test Design"

Content of "Essential Software Test Design" 2015-11-16 PART I 7 TEST DESIGN TECHNIQUES: AN OVERVIEW PART II 8 THE OVERARCHING PROCESS OF TEST DESIGN 12 FROM USE CASES TO TEST CASES 13 STATE ...

weixin_33971130的博客 173
上一篇: GCC 对C语言的扩展
下一篇: 用C实现面向对象
andyhuabing
博客等级 码龄19年 704粉丝 165原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值