连载:面向对象葵花宝典:思想、技巧与实践(26) - 类模型三板斧

面向对象葵花宝典-电子版 面向对象是目前最流行的一种程序设计和实现思想,无论你是从事企业级开发、互联网应用开发,还是手 机软件开发,都会使用到面向对象的技术;主流的编程语言中,C++,Java,C#,PHP,Python等都是支持 面向对象的语言;编程排行榜前十的语言中,面向对象的编程语言能够稳定占据7~8席。所有的这 些现象,都展示了面向对象的流行程度和受欢迎程度。本书就对面向对象做了较为系统的介绍。 立即下载

类模型设计其实就是程咬金打天下 -- 三板斧 而已 :)


第一斧(照猫画虎):领域类映射

面向对象类设计首先要解决的一个问题是:类从哪里来 ?


有的人可能会认为,要发挥想象力、创造力。。。。。等各种“力”——这种方法的主要问题是:我们不是在进行纯粹的艺术创造,而是要最终满足客户需求,而不能天马行空。


有的人可能会想到,参考其它的系统吧,把类似系统拿过来改吧改吧 ——这种方法的主要问题是:如果没有其它类似系统给你参考呢 ?
还有的人干脆就说:拍脑袋吧,凭感觉吧 —— 这种方法的主要问题是:猴子能敲出莎士比亚全集么 ?

看起来以上方法都不太可行,那究竟如何才能从哪里找到我们需要的类呢?


相信绝大部分认真看书的同学都会灵光一闪:领域模型。
我们将上一章中的领域模型图拿出来,重新再看一下:


相信不用我多说,绝大部分同学一眼就能看出:哇塞,这不就是类么?


确实是这样的,领域模型中的“领域类”,是设计模型中“软件类”最好的来源。通过“领域类”来启发我们设计最初的“软件类”,具有如下几个明显的优点:
1)软件类来自领域类,领域类来自用例,用例来自客户,这样一环扣一环,软件类的正确性得到了保证,不用担心拍脑袋带来的问题;
2)领域类到软件类的转换非常简单,不需要天才的创新,或者丰富的想象力,只要掌握基本的面向对象的知识就能完成,菜鸟也能做设计;
3)不需要参考其它系统,不用担心没有参照物时无法设计的问题;


从领域类到软件类的转换操作非常简单,基本上就是一个照猫画虎的过程。
【类筛选】
虽然我们说从领域类到软件类是一个照猫画虎的过程,但并不意味着将领域类全盘拷贝过来即可。主要的原因在于“软件类”是软件系统内部的一个概念,而领域类是业务领域的概念,并不是每个领域类最终都会体现在软件系统中。


以POS机的领域类为例,领域类“顾客”不需要转换为软件类,因为顾客是POS机业务领域的一个重要参与者,但并不是POS机内部需要实现的一个实体,在POS机业务中,顾客甚至都不是和POS机直接交互的实体,站在POS软件系统的角度来说,顾客和POS机其实没有任何关系。

对于屏幕、键盘、扫描仪这些输入输出设备,一般情况下我们认为它们是POS机系统硬件的一部分,而并不是POS机软件系统的一部分。但假如POS机有一个需求是既支持图形界面输出,又支持字符界面输出,那么POS的软件系统就需要处理这种和屏幕相关的需求了,此时屏幕就是POS机软件系统的一部分了,需要将领域类转换为软件类。为了简单处理,接下来的分析中,输入输出设备不做转换。

经过筛选后,剩下的领域类就需要都转换为软件类,具体如下:
收银员、商品、交易、小票、支付、信用卡、会员卡、现金、购物卡。

【名称映射】
筛选完成后,我们开始讲领域类转换为软件类,转换的方法很简单,首先不管三七二十一,将每个领域类都用一个软件类与对应,名称都保持一样即可。

有的同学可能担心这样设计是否会不符合面向对象设计的要求,是否会导致设计质量不高。。。。。。等等,其实这种担心是多余的,因为我们后续还有很多工作要做,目前做的只是一个开始工作。

【属性映射】
通过名称映射的方法得到软件类后,接下来就是要设计类的属性了。由于领域类中也已经有了属性,因此我们也只需简单的照搬过来即可。

【提炼方法】
软件类的属性设计完成后,接下来就需要设计软件类的方法了。但这次我们就没有那么好的运气了,因为领域类中并没有方法!因此我们不能通过简单映射的方法来获取方法,必须采取其它手段。

和类的设计一样,类方法的设计同样不能采取“创造力、参考其它系统、拍脑袋”等方式来完成,为了确保正确性,类的方法设计也同样应该能够从已有的模型中推导出来。

由于已经明确领域模型中没有方法了,因此就不能从领域模型中得到软件类的方法,剩余只有一个“用例模型”了,因此我们锁定“用例模型”,看看如何从中找到我们所需要的方法。

其实方法也很简单,概括一下就是:找动词。
你可能不敢相信自己的眼睛,这么简单,那几乎初中生都会做设计啊,找动词谁不会呢?

然而不管你信不信,这一步确实是这么简单,当然,如果面向对象设计只是到此为止,那确实初中生也是可以做的,但实际上这只是面向对象类设计的开始步骤而已,后面的工作还多着了,所以完全不用担心初中生来抢你的饭碗。

我们以POS机为例,来看看如何通过“找动词”这种技巧来找到软件类的方法。
如下是POS机的用例,我们将相关动词都加粗显示:

【用例名称】

买单

【场景】

Who:顾客、收银员

Where:商店的收银台

When:营业时间

【用例描述】

1. 顾客携带选择好的商品到收银台;

(这一步没有异常)

2. 收银员逐一扫描商品条形码,系统根据条形码查询商品信息;

2.1 扫描仪坏了,必须支持手工输入条形码;

2.2 商品的条形码无法扫描,必须支持手工输入条形码;

2.3 条形码能够扫描,但查询不到信息,需要收银员和顾客沟通,放弃购买此产品

3. 扫描完毕,系统显示商品总额,收银员告诉顾客商品总额;

(这一步没有异常)

4. 顾客将钱交给收银员;

4.1 顾客的钱不够,顾客和收银员沟通,删除某商品;

4.2 顾客的钱不够,顾客和收银员沟通,删除某类商品中的一个或几个(例如买了5包烟,去掉两包)

4.3 顾客觉得某个商品价格太高,要求删除某商品;

4-A:顾客使用信用卡支付

4-A.1 信用卡支付流程(请读者自行思考完善,可以写在这里,如果太多,也可以另外写一个子用例)

4-B:顾客使用购物卡支付

        4-B.1 购物卡支付流程

4-C:顾客使用会员卡积分支付

        4-C.1 会员卡积分支付流程

5. 收银员清点钱数,输入收到的款额,系统给出找零的数目;

(这一步没有异常)

6. 收银员将找零的钱还给顾客,并打印小票;

7. 买单完成,顾客携带商品和小票离开;

【用例价值】

顾客买完单以后,就可以携带商品离开,而超市也将得到收入;

【约束和限制】

1. POS机必须符合国标XXX;

2. 键盘使用中文,因为收银员都是中国人;

3. 一次买单数额不能超过99999RMB;

4. POS机要非常稳定,至少一天内不要出现故障;



标识出所有的动词后,还需要进一步的工作:
【筛选】
并不是所有的动词都一定是软件类的方法,我们需要将这些动词识别出来并排除在后续设计范围之外。
例如:
“顾客携带选择好的商品到收银台”:这里的“携带”是顾客的一个动作,而顾客并不是我们的软件类;
“收银员告诉顾客商品总额”:这里的“告诉”确实是收银员的一个动作,而且“收银员”确实也是我们的软件类,但这里也要排除“告诉”,因为“告诉”这个动作和POS系统并没有关系,只是业务流程中的一个步骤而已。
其它需要排除的动词还有:“需要收银员和顾客沟通”、“顾客将钱交给收银员”、“收银员清点钱数”、“收银员将找零的钱还给顾客”、“顾客携带商品和小票离开”
【提炼】
筛选完不需要的动词后,剩下的就是我们需要的动词了,但此时并不能简单的将所有动词拿出来直接扔给某个软件类就行了,我们还需要进行一些加工。

继续以POS机为例:
“收银员逐一扫描商品条形码”:这里的“扫描”看起来是“收银员”的一个动作,而且“收银员”确实也是我们的软件类,但其实深究一下,“扫描”这个动词并不能分配给“收银员”这个软件类,因为真正执行“扫描”功能的是“扫描仪”,收银员只是拿着扫描仪扫描商品,并不是收银员自己去读取商品条形码;类似的动词还有“必须支持手工输入条形码”,也不能算作“收银员”的功能。

那我们为什么不排除这两个动词呢?秘密就在于我们要从这两个动词提炼出软件类的方法。稍作分析,我们就可以发现,无论是“扫描条形码”,还是“手工输入条形码”,其实最终的目的都是“添加本次交易的商品”,因此我们可以提炼出“增加交易商品”的动词。

还有一种提炼的方法需要从已有的动词中推断出来,例如:“扫描完毕,系统显示商品总额”,这里只提到了“显示”这个动词,但相信大部分人都能一眼看出,“显示”之前肯定要“计算”,不然显示出来的值从哪里来呢?

有的朋友可能会疑惑,为什么不在用例的时候就写清楚呢?例如:扫描完毕,系统计算商品总额,然后系统显示商品总额。这样不就一目了然的看出来了么?

理想情况下这种想法当然没错,但现实往往没有那么美好,写用例的产品人员可能经验不足,也可能表达能力有限,还有可能比较马虎,或者遗漏了。。。。。。总之会有很多异常情况,因此设计人员必须具备这样的推断和判断能力。

经过这一步骤后,我们获得的动词如下:
* 增加商品
* 计算商品总额
* 显示商品总额
* 删除商品
* 现金支付
* 信用卡支付
* 购物卡支付
* 会员卡积分支付
* 打印小票


当然,以上列出来的动词并不是就一定是100%的标准答案,不同的人来进行分析和设计,可能略有不同,但总体应该比较相似,毕竟业务是一样的,而业务需求就是设计最强的约束。

【分配】
识别出有效的动词后,最有一步就是分配了,即:将从用例中提炼出来的动词,分配给已经有了属性的软件类。这种分配操作很多时候都是按图索骥,特别是对于有领域经验的人来说,基本上凭直觉就能基本分配正确。

当然,如果你的经验并不是很丰富,那么还是老老实实的一个一个来分析吧。

以POS机为例:
* 增加商品:很明显应该分配给“交易”类
* 计算商品总额:分配给“交易”类
* 显示商品总额:分配给“交易”类
* 删除商品:分配给“交易”类
* 现金支付:分配给“现金”类
* 信用卡支付:分配给“信用卡”类
* 购物卡支付:分配给“购物卡”类
* 会员卡积分支付:分配给“会员卡”类
* 打印小票:这个动词的分配存在一定的灵活性,有的人可能认为应该分配给“交易”类,因为打印小票可以认为是“交易”流程中的一个步骤;有的人可能认为应该分配给“小票”类,因为打印小票可以认为是“小票”类的一个基本功能。其实两者都有一定道理,如果没有其它更有力的选择因素,我建议根据个人经验选择一个即可,这里我们选择分配给“小票”。
分配完成后,我们可以看到“交易”、“小票”、“信用卡”、“购物卡”、“会员卡”、“现金”都已经有方法了。

当然,对于有经验的人来说,以上步骤完全可以在脑海中就迅速完成了,而并不会这样一步一步的演示给别人看,所以看起来就像变戏法一样,不知怎么就设计出来了很多的软件类。

经过上面的处理步骤后,我们得到如下的类图:


与领域模型相比,部分领域类被剔除了,留下来的领域类映射成软件类后,又增加了方法。虽然还不完善,但软件类的是越来越有型,越来越清晰了。


第二斧(精雕细琢):应用设计原则和设计模式
完成了从领域类到软件类的映射后,类出来了,属性也出来了,方法也有了,看起来设计已经大功告成了。
事实上也确实有很多人基本上做到这一步就开始动手编码了,而且经过一番拼搏,最后发布的系统也能用。

但相信很多人都会有这个疑问:这样做就够了么,这样设计是否是好的设计呢?
要回答这个问题,我们首先要明确:什么叫做“好”的设计呢 ?

到目前为止,我们已经有了一个类的设计模型,而且如果按照这个模型去实现的话,最终应该也是能够满足用户的需求,毕竟我们这个类模型是按照“需求模型 -> 领域模型 -> 类模型”这样一路推导过来的,不会出现大的偏差。

那么,满足了用户需求的设计就是好的设计么?
相信有经验的朋友都会知道答案:“满足用户需求”只是设计的一个最基本要求,而不是一个“好设计”的评判标准。

既然如此,那么到底什么才是好的设计呢,是否有明确的标准来进行评价呢?
幸运的是,面向对象领域经过几十年的发展,确实已经发展出了很多成熟的指导思想和方法,用于评价和指导如何才能做好面向对象的设计。其中最具代表性的就是“设计原则”和“设计模式”。


【设计原则】
当我们谈到面向对象领域的设计原则的时候,我们其实都是在谈论罗伯特.C.马丁(Robert C. Martin ,又叫Bob大叔)的SOLID原则。

这也难怪,Bod大叔实在是太牛了,面向对象领域的设计原则几乎被他全部包揽了,加上他在他的畅销书《敏捷软件开发:原则、模式与实践》中详细的将这些原则集中一 一阐述,面向对象领域设计原则的权威非他莫属。毫不夸张的说,Bob大叔的威名和在面向对象领域中的地位,和设计模式的“四人帮”是不相上下的。

虽然很多资料都将SOLID原则和敏捷开发、测试驱动开发等方法绑定在一起,但我觉得只要是面向对象设计,不管是瀑布流程、、CMM流程、RUP流程、还是敏捷开发流程,都应该应用设计原则以提高设计质量。

参考wiki百科,SOLID设计原则简单介绍如下:
SOLID实际上是取5个设计原则的首字母拼起来的一个助记单词。具体的设计原则如下(详细的设计原则,我们会在后面详细阐述,这里不再详细展开):

首字母

英文简写

英文名称

中文名称

说明

S

SRP

Single Responsibility Principle

单一职责原则

对象应该只具备单一职责

O

OCP

Open/Close Principle

开放/封闭原则

认为“软件体应该是对于扩展开放的,但是对于修改封闭的”的概念。

L

LSP

Liskov Substitution Principle

Liskov替换原则

认为“程序中的对象应该是可以在不改变程序正确性的前提下被它的子类所替换的”的概念

I

ISP

Interface Segregation Principle

接口隔离原则

多个特定客户端接口要好于一个宽泛用途的接口

D

DIP

Dependency Inversion Principle

依赖反转原则

依赖于抽象而不是一个实例


(wiki百科链接如下:
http://zh.wikipedia.org/wiki/SOLID_(%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E8%AE%BE%E8%AE%A1))

前面我们简单的八卦了一下,现在回归正题:设计原则有什么用?
其实和所有的原则一样,设计原则也是一个判断标准,说通俗点,设计原则就像是木匠手中的尺子,尺子是用来衡量木材的长短的,而设计原则就是衡量类设计的“尺子”:量一量,看长了还是短了,还是正好,长了就裁短一些,短了就加长一些。经过如此衡量并调整,最终就能够得到我们希望的设计作品。

当然,和木匠的尺子稍有不同,木匠不用尺子就做不出能用的家具,但我们不用设计原则的话,其实还是能够做出满足需求的系统的。

既然这样,我们为什么一定要用设计原则呢?ARTHUR J.RIEL在《OOD启思录》一书中针对这个问题给出了非常形象的解释:
你不必严格遵守这些原则,违背它也不会被处以宗教刑罚。但你应当把这些原则看做警铃,若违背了其中的一条,那么警铃就会响起。”-------ARTHUR J.RIEL,《OOD启思录》

也就是说,如果违背了这些设计原则,就可能有危险,但究竟是什么危险呢,警铃要警告我们什么呢,是火灾、水灾、地震、陷阱、还是有狮子、老虎。。。。。?

要回答这个问题,还需要回到面向对象的本源:我们在第一章解释为什么要面向对象的时候提到了面向对象的核心思想是“可扩展性”,这其实就是我们应用设计原则的根本目的:保证可扩展性。如果我们不遵守这些设计原则,警铃就会响起,提醒我们:你的设计可扩展性会有问题!

除了设计原则外,后面要讲到的设计模式,其本质也是为了提高可扩展性。这也是为什么我们通过领域类映射得到了很多软件类之后,还需要不辞辛劳的继续应用设计原则和设计模式的主要原因,本质上都是为了提高设计的可扩展性。

SOLID设计原则的各个子原则详细介绍会在后面详细介绍,这里我们简单的以POS机为例,看看如何应用设计原则。

仔细观察我们通过领域类映射得到的软件类,可以发现一个很明显不符合SOLID原则中的DIP原则的地方,即:“交易类”直接依赖“会员卡”、“购物卡”、“信用卡”、“现金”4个子类,这样的实现不符合DIP原则,当需要增加新的支付方式时,“交易类”也需要跟着修改。

既然不满足DIP设计原则,那么我们就按照DIP原则的要求,提取出一个支付的父类来,即:“交易类”依赖“支付类”,“会员卡”、“购物卡”、“信用卡”、“现金”都继承“支付”类。具体实现如下:



可以看到,应用DIP设计原则之后,我们又多出了一个“支付”的类,这个类原来在领域模型中是没有的,而是我们在设计阶段“创造”出来的。

对于其它各个类,我们都可以依次使用设计原则进行判断,当发现不符合设计原则的设计时,就采取增加、删除、合并、拆分等手段,使我们的设计逐步改进,最终达到符合设计原则的目的。

【设计模式】
相比设计原则来说,设计模式更加普及和流行,当我们谈到设计方法的时候,大部分人肯定都会想到设计模式,设计模式如此深入人心,几乎到了言必谈设计模式的地步。

和设计原则类似,当我们谈论设计模式的时候,我们其实都是在谈论GOF(Gang of Four,中文翻译为“四人帮”)在经典名作《设计模式  --可复用面向对象软件的基础》一书中提到的设计模式。

通俗的讲,设计模式是用于指导我们如何做出更好的设计方案,而前面提到的设计原则,其作用也是这样的。那么,设计原则和设计模式,我们该如何选择?

有的朋友可能会以为这两个是二选一的关系,要么用设计原则,要么用设计模式。这种理解是错误的,设计原则和设计模式并不是竞争关系,正好相反,它们是互补的关系。

设计原则和设计模式互补体现在:设计原则主要用于指导“类的定义”的设计,而设计模式主要用于指导“类的行为”的设计,更通俗一点的讲:设计原则是类的静态设计原则,设计模式是类的动态设计原则。
一般情况下,我们是采用“先设计原则,后设计模式”的方法来操作的。

设计模式的相关内容会在后文详细介绍,这里我们以POS机为例,看看如何应用设计模式来优化我们的设计。

通过分析应用设计原则优化后的类,我们发现“信用卡”这个类存在优化的空间,因为国际上存在不同的信用卡,最常见的有中国银联(UnionPay)、Visa、MasterCard这几种,每种信用卡在支付的时候需要接入不同的机构,其接入方式和协议肯定都是有一定差异的。为了封装这种差异以支持后续更好的扩展,我们应用设计模式的Bridge模式,提取出“信用卡处理”这个类,这个类的主要处理“连接、认证、扣款”这样的职责。UnionPay、Visa、MasterCard都继承“信用卡处理”这个类。具体如下:




第三斧(照本宣科):拆分辅助类
经过前面的设计步骤之后,面向对象类的设计工作已经完成,我们输出了完整的类模型,看起来已经可以开始动手编码了,你是否舒了一口气,看着自己的设计作品,不由得产生了一种自豪感呢?

确实值得自豪,毕竟我们一步一个脚印,从最初仅仅存在于客户脑袋中的需求,逐步的推导、演变、设计出了能够付诸实施的类模型了。但在最终实施之前,还有一点小小的动作要完成,这就是我们的拆分辅助类操作。

拆分辅助类的主要目的是为了使我们的类在编码的时候能够满足一些框架或者规范的要求。比如说常见的MVC模式,将一个业务拆分成Control、Model、View三个元素;J2EE模式中,将对象分为PO、BO、VO、DTO等众多对象。

之所以说这是一点小小的动作,是因为这个动作确实很简单,只要将我们设计出来的类,按照规范要求,一 一对应分拆即可。

以POS机为例,假如我们的框架要求提供DAO对象,负责数据库的相关操作,则“购物卡”类就应该拆分为两个:“购物卡”、“购物卡DAO”,其中“购物卡”用于负责提供“支付”功能给“交易”类调用,“购物卡DAO”用于负责从数据库读取购物卡信息,修改数据库中购物卡余额等操作。


需要注意的是,拆分设计辅助类仅仅是为了满足框架或者规范的要求,本身并不是一个设计的步骤,而是实施的一个步骤,所以我们一般都不需要将拆分的辅助类体现在类模型中,仅仅在编码的时候拆分即可。


================================================ 
转载请注明出处:http://blog.youkuaiyun.com/yunhua_lee/article/details/23738671
================================================ 

面向对象葵花宝典 思想、技巧与实践 本书系统地讲述了面向对象技术的相关内容,包括面向对象的基本概念、面向对象开发的流程、面向对象的各种技巧,以及如何应用面向对象思想进行架构设计。在讲述相关知识或技术的时候,除了从“是什么”这个角度进行介绍外,更加着重于从“为什么”和“如何用”这两个角度进行剖析,力争让读者做到“知其然,并知其所以然”,从而达到在实践中既能正确又能优秀地应用面向对象的相关技术和技巧。 作者简介 立即下载

相关推荐

高清-面向对象葵花宝典 思想、技巧与实践(PDF带目录)

这个本是推荐给新人向软件设计过渡的一本书,很有实用价值。值得拥有!

连载:面向对象葵花宝典:思想、技巧与实践(3) - 面向过程 vs 面向对象

从理论的角度对比“面向对象”和“面向过程”两种编程思想的差异,提出了面向对象的程序 = 对象 + 交互 的新颖说法

华仔-技术博客 8280

利用PV操作控制进程的并发进行---经典题解

前趋图 先理清楚前趋图中的逻辑关系:P1没有前驱,P2的前驱是P1,P3的前驱是P1、P2,P4的前驱是P2,P5的前驱是P3、P4。 前驱就是指只有在前驱进程完成后,该进程才能开始执行。由图可知,这里进程之间有6条有向弧,分别表示为P1→P2,P1→P3,P2→P3,P2→P4,P3→P5,P4→P5, 各个进程间的逻辑关系,那么我们需要设定6个信号量(S1、S2、S3、S4、S5、S6),利用PV操作来控制这些过程。 对于第一个空,P1执行完成之后,需要通知P2、P3可以开始,此处需要V(S

Yan Ka Kue的博客 6137

连载:面向对象葵花宝典:思想、技巧与实践(1) - 程序设计思想的发展

史前时代:面向机器 最早的程序设计都是采用机器语言来编写的,直接使用二进制码来表示机器能够识别和执行的指令和数据。简单来说,就是直接编写0和1的序列来代表程序语言。例如:使用0000 代表 加载(LOAD),0001 代表 存储(STORE)等。   机器语言由机器直接执行,速度快,但一个很明显的缺点就是:写起来实在是太困难了,一旦你发现自己写错了,改起来更蛋疼!这样直接导致程序编写效率十分

华仔-技术博客 1万+

Unity游戏开发实战:用Flow Field实现RTS百人军团流畅寻路(附完整代码)

本文深入探讨了在Unity中利用流场寻路技术解决RTS游戏大规模单位移动性能瓶颈的实战方案。通过解析从Dijkstra算法生成成本场、积分场到最终向量场的核心原理,并结合分块、缓存及与DOTS/ECS架构集成的优化策略,实现了百人军团的流畅群体寻路。文章提供了完整的代码示例,助力开发者构建高性能的RTS寻路系统。

weixin_28363123的博客 587

ndnSIM学习笔记(一)

在接下来的一段时间要用ndnSIM来做自己的仿真网络,需要系统的学习相关内容,以下为内容记录。1.安装      1.1核心依赖(必需的)             • python >= 2.6             • libsqlite3             • libcrypto++             • pkg-config             • Boost lib...

gaonjzzz的博客 2985

连载:面向对象葵花宝典:思想、技巧与实践(25) - 类模型

面向对象设计和弹吉他差不多,有很多成熟的理论和技巧,学会弹吉他并不难,但要成为吉他高手或者大师,还是要靠个人天分!【师傅领进门,修行在个人】“类模型”是整个面向对象设计模型的核心,是面向对象设计阶段的主要输出,也是设计师们最能够发挥自己才能的地方。 虽然“类模型”如此重要,但面向对象设计技术经过几十年的发展后,目前已经形成了很成熟的一套体系,因此真正在进行“类模型”设计的时候,其实难度并不高,这也

华仔-技术博客 4891

【1.2】Costas环的基本原理概述

Costas环是一种用于载波恢复的相干解调技术,可直接从BPSK等抑制载波信号中恢复本地载波并完成解调。其核心结构包含同相/正交双支路处理,通过混频、低通滤波后,利用I/Q支路信号乘积进行相位误差检测,经环路滤波器调节VCO输出频率,实现载波同步。课程将重点讲解Costas环的MATLAB仿真实现、系统性能分析及FPGA开发,包括信号产生、频偏模拟、滤波器设计等模块,并通过AWGN信道和不同频偏条件下的测试验证系统性能。该技术无需单独提取载波,在数字通信系统中具有重要应用价值。

fpga/matlab/simulink算法仿真工程 451

你说写代码,最常用的3个设计模式是啥?

不用多,也就3个设计模式,足够熟练就能让代码干净整洁。就像三十六路宣花斧,程咬金也只是学了3招,就能封卢国公,列凌烟阁二十四功臣之一。

bugstack虫洞栈 2520

自建 HTML获取腾讯六宫格点选图片验证码素材,实现刷新批量获取图片方便训练

通过自建 HTML 页面,可以方便地获取腾讯六宫格二维码素材,不仅过程简单,而且可以灵活配置各种参数。希望这篇文章能帮助到需要相关素材的小伙伴。如果你有其他问题或者更好的方法,欢迎留言交流!

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 489

【PHP面试题29】什么是PHP-FPM?它与PHP和Nginx有什么关系

PHP面试专区。计划将全覆盖PHP开发领域所有的面试题,对标资深工程师/架构师序列,欢迎大家提前关注锁定。PHP-FPM(FastCGI Process Manager)是PHP的FastCGI进程管理器,它是PHP 5.3.3及更高版本的一部分。它通过为每个请求分配一个独立的进程来提高PHP脚本的执行效率和性能,并且可以与Web服务器(如Nginx、Apache等)进行通信。PHP-FPM是PHP的FastCGI进程管理器,它通过为每个请求分配一个独立的进程来提高PHP脚本的执行效率和性能。

黑夜开发者的博客 1477

设计模式系列-面向对象葵花宝典-面向对象基础

设计模式系列-面向对象葵花宝典-面向对象基础声明:本系列为面向对象葵花宝典一书学习总结内容,原作者博客链接书籍简介 面向对象葵花宝典:思想、技巧与实践》系统地讲述了面向对象技术的相关内容,包括面向对象的基本概念、面向对象开发的流程、面向对象的各种技巧,以及如何应用面向对象思想进行架构设计。在讲述相关知识或技术的时候,除了从“是什么”这个角度进行介绍外,更加着重于从“为什么”和“如何用”这两个角度

那远远的云端 2990

机器学习的低代码与无代码平台:便捷入门之路

机器学习领域正涌现出大量低代码和无代码平台,使非技术人员也能轻松应用AI技术。低代码平台(如PyCaret、H2O AutoML)需少量编程但灵活性强,而无代码工具(如Google Cloud AutoML、Teachable Machine)则完全无需编程基础。这些平台覆盖图像识别、文本处理、业务预测等多种场景,适合快速部署简单项目。但专业人士仍需注意,这些工具无法替代复杂场景下的定制化开发。随着技术进步,低门槛AI工具正在改变各行业的创新方式。

2501_90323865的博客 154

连载:面向对象葵花宝典:思想、技巧与实践(40) - DECORATOR模式

掌握了设计模式之道后,我们将以全新的方法来理解设计模式,这个方法更简单、更直观,不信?看几个样例就知道了=====================================================================【业务】假设你进入了一个信息安全管理非常严格的公司,这家公司不允许员工自行打印文档,所有的文档打印都需要交给文档打印系统统一管理。文档打印系统会记录每次打印的

华仔-技术博客 5035

ArcGIS笔记13_利用ArcGIS制作岸线与水深地形数据?建立水动力模型之前的数据收集与处理?

在利用MIKE建立水动力模型之前,需要收集、处理和制作诸多数据和资料,主要有岸线数据、水深地形数据、开边界潮位驱动数据、风场数据、潮位和海流观测资料和站点潮汐调和常数资料等。本篇主要介绍这些资料的获取与处理。

晏长街的博客 5948

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

葵花宝典 七 面向对象

21、写clone()方法时,通常都有一行代码,是什么?clone 有缺省行为,super.clone();因为首先要把父类中的成员复制到位,然后才是复制自己的成员。 面向对象的特征有哪些方面? 封装: 隐藏对象内部的复杂性,只对外公开简单的接口。便于外界的调用,从而提高了系统的可扩展性,可维护性。 封装的要点: 类的属性的处理: 1.一般使用private 2.提供相应的get、set

请叫我法斗先生 301

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

软件建模与设计 —— 入门

对于软件建模与设计,非科班出身的同学可能和我一样比较陌生,虽然日常开发中也涉及到建模,但是并没有系统的学习过软件建模设计。类似于设计模式,软件建模与设计也有一套三板斧。

四问四不知的博客 2362

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

连载:面向对象葵花宝典:思想、技巧与实践(27) - 动态模型设计

类模型指导我们如何声明类,动态模型指导我们如何实现类!动态模型设计一般都是在类模型设计完成后才开始,因为动态模型设计的时候一般都需要用到类模型中的类。相对类模型来说,动态模型要相对简单一些,主要原因在于动态模型设计的时候没有什么设计原则和设计模式需要应用,只需要对照用例模型,根据用例模型的特点,选取一个合适的动态模型将其表述出来即可。动态模型在实际开发过程中有非常重要的作用,简单来说,如果没有动态

华仔-技术博客 5631

连载:面向对象葵花宝典:思想、技巧与实践(30) - SRP原则

前面详细阐述了“高内聚低耦合”的总体设计原则,但如何让设计满足这个原则,并不是一件简单的事情,幸好各位前辈和大牛已经帮我们归纳总结出来了,这就是“设计原则”和“设计模式”。毫不夸张的说,只要你吃透这些原则和模式并熟练应用,就能够做出很好的设计。==================================================================【SRP原则详解】SRP

华仔-技术博客 4934

设计模式系列-面向对象葵花宝典-面向对象技巧

设计模式系列-面向对象葵花宝典-面向对象技巧声明:本系列为面向对象葵花宝典一书学习总结内容,原作者博客链接第三部分:面向对象技巧8. 设计原则 8.1. 内聚和耦合 内聚 是否专注模块的职责,是内聚性的充要条件 是否与模块处理的内容相关 耦合 耦合(或者称依赖)是程序模块相互之间的依赖程度 内聚关注模块内部的元素

那远远的云端 713

把书读薄之《面向对象葵花宝典》阅读笔记-面向对象实战

《面向对象葵花宝典》是网友爱技术的华仔的一个技术专栏里的文章,我在逐篇阅读之后,最大的感觉就是这个面向对象编程系列是货真价实的来自技术前线工程师的经验之作,是作者工作经验的总结和升华,对面向编程的方方面面有指导意义,在这里强烈推荐给面向对象领域的朋友们,原文链接如下:http://blog.youkuaiyun.com/column/details/oobaodian.html 以下是个人阅读之后,

cheyiliu的专栏 1223

连载:面向对象葵花宝典:思想、技巧与实践(8) - “接口” 详解

“接口”是我见过的面向对象领域中滥用、乱用、误用最多的术语: 有的人说:兄弟,给我提供一个“查询XXX”的接口。。。。。。 有的人说:系统对外提供了“查询”、“插入”、“更新”、“删除”4个接口。。。。。。 有的人说:我们要基于“接口”编程。。。。。。 有的人说:你这样做破坏了我们的接口设计。。。。。。 。。。。。。。。。。。 倒不是在这里指责他们的水平有多差,而是接口这个属于的中文翻

华仔-技术博客 5734

连载:面向对象葵花宝典:思想、技巧与实践(5) - 面向对象迷思:面向对象导致性能下降?

面向对象会导致性能降低? 这是一个在IT江湖流传已久的传说,很多对面向对象不甚了解、或者一知半解的人,每当需要抵触面向对象时,就会把这条“金科玉律”拿出来救驾!   更要命的是,每个相信这个传说的人都会举一个看起来很显而易见的例子:C和Java的对比!   你可以到网上搜索一大堆C和Java的性能对比,你自己也可以做一个简单的对比测试,我毫不怀疑测试结果肯定是C快,但这能证明面向对象导致

华仔-技术博客 5306

连载:面向对象葵花宝典:思想、技巧与实践(34) - DIP原则

DIP,dependency inversion principle,中文翻译为“依赖倒置原则”。 DIP是大名鼎鼎的Martin大师提出来的。他在1996 5月的C++ Reporter发表“ The Dependency Inversion Principle”的文章具体阐述了DIP原则,而且在他的经典著作《 Agile Software Development, Principles, ...

weixin_34259232的博客 156

连载:面向对象葵花宝典:思想、技巧与实践(38) - 设计模式之道

很多人能够熟练背诵出所有的设计模式,能够快速画出各种设计模式的UML类图,也能够熟练的写出《设计模式》一书中各个模式的样例代码。但一到实际的项目设计和开发的时候,往往都会陷入迷茫:要么无从下手,不知道哪个地方要用设计模式;要么生搬硬套,胡乱使用设计模式,将方案和代码搞得一团乱麻。============================================================

华仔-技术博客 6141
上一篇: 连载:面向对象葵花宝典:思想、技巧与实践(25) - 类模型
下一篇: 连载:面向对象葵花宝典:思想、技巧与实践(27) - 动态模型设计
华仔爱技术
华仔爱技术 领域专家: 学术研究与理论基础技术领域 领域专家: 学术研究与理论基础技术领域 业界专家认证 业界专家认证
博客等级 码龄21年 4990粉丝 140原创
评论 9
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值