软件的坏味道

软件系统设计 - 代码优化 代码重构 - 代码坏味道对应的重构手法参考列表 学会根据一些迹象来判断当前的代码表现是否合理,发现存在的坏味道,选取最合适的重构手法开始重构工作。因此程序员必须培养自己的判断力, 阅读详情

1) Duplicated Code(重复代码)

2) Long Method(过长函数)

3) Large Class(过大类)

4) Long Parameter List(过长参数列)

5) Divergent Change(发散式变化)——过耦合

6) Shotgun Surgery(散弹式修改)——过度的分散与过耦合相反

7) Feature Envy(依恋情节)——函数对某个class的兴趣高过对自己所处的host class的兴趣。症状:某个函数为了计算某值,从另一个对象那调用机会半打的取值函数。疗法:把这个函数移动到另一个地点。

8) Data Clumps(数据泥团)——症状:总是绑在一起出现的数据,很多地方可以看到相同的三或四笔数据项:两个classes内的相同值域、许多函数签名式中的相同参数。疗法:把这些数据放进属于它们自己的对象中。

9) Primitive Obsession(基本型别偏执)——两种数据:结构型别和基本型别。充分利用“对象”的价值,它模糊了横亘于基本数据和体积较大的classes之间界限。例如以class表示字符串和日期。

10) SwitchStatements(switch惊悚现身)——面向对象程序的一个最明显特征就是:少用switch语句。多态的概念可以为此带来优雅的解决办法。

11) ParallelInheritance Hierarchies(平行继承体系)——每当为某个class增加一个subclass,必须也为另一个class相应增加一个subclass。

12) Lazy Class(冗赘类)——如果一个class的所得不值其身价,他就应该消失。

13)Speculative Generality(夸夸其谈未来性)——以为“总有一天需要做这事”并因而企图以各式各样的挂钩和特殊情况来处理一些非必要的事情。

14) TemporaryField(令人迷惑的暂时值域)——对象内某个instance变量仅为某种特定情势而设。

15) MessageChains(过度耦合的消息链)——用户向一个对象所求另一个对象,然后再向后者所求另一个对象,然后……这就是消息链。

16) Middle Man(中间转手人)——某个class接口有一般的函数都委托给其他class,这样就是过度运用。

17)Inappropriate Intimacy(狎昵关系)——两个类之间过分亲密

18)Alternative Classes with Different Interfaces(异曲同工的类)——两个函数做同样的事情,却有着不同的签名式。

19) IncompleteLibrary Class(不完美的程序库类)

20) Data Class(纯稚的数据类)——只含有一些值域以及访问值域的方法

21) RefusedBequest(被拒绝的遗赠)——子类应该集成弗雷的函数和数据。但如果他们不想或不需要继承。

22) Comments(过多的注释) 
软件测试·坏味道 1. Duplicated Code (重复代码) 重复代码就是不同地点,有着相同的程序结构。一般是因为需求迭代比较快,开发小伙伴担心影响已有功能,就复制粘贴造成的。重复代码很难维护的,如果你要修改其中一段的代码逻辑,就需要修改多次,很可能出现遗漏的情况。 如何优化重复代码呢?分三种情况讨论: 同一个类的两个函数含有相同的表达式 classA{ publicvoidmethod1(){ doSomething1 doSomething2...... 阅读详情

相关推荐

软件重构技术(重构介绍、重构原则、代码的坏味道。。。)

任何一个傻瓜都能写出计算机可以理解的程序,只有写出人类容易理解的程序才是优秀的程序员

每个程序员都应牢记的7种坏味道,11种原则,23种模式

每个程序员都应牢记的7种坏味道,11种原则,23种模式 (一)7种设计坏味道 1.僵化性: 很难对系统进行改动,因为每个改动都会迫使许多对系统其他部分的其它改动。 2.脆弱性: 对系统的改动会导致系统中和改动的地方在概念上无关的许多地方出现问题。 3.牢固性: 很难解开系统的纠结,使之成为一些可在其他系统中重用的组件。 4.粘滞性: 做正确的事情比做错误的事情要困难。 5....

梁飞的博客 2496

Linux 使用rm -rf /*命令后,恢复系统方法

Linux 使用rm -rf /*命令后,恢复系统方法 个人学习记录 这里实验环境采用的是radhel7.1的版本: 个人认为核心就是缺失什么组件,就从别的地方复制什么组件过来,先把系统拉起来,再慢慢恢复配置 进入救援模式 1、将/dev/sda两个分区分别挂载看看,里面的内容,有内容的就是根存在的分区 2、ifconfig eno16777777 192.168.8.2 3、从另外一台一样系统的根 。用 tar打包,一个个文件夹拷贝过来 4、到坏系统,scp另外一个系统的etc.tar.gz 5

weixin_43603476的博客 1万+

对软件代码坏味道的认识

指代码表面的腐化现象,对需求易变性的估计不足、功能重复出现、片段式植入等代码腐化现象。(1)滥用面向对象(2)膨胀剂(3)可有可无(4)难以修改和耦合。

代码充实生活的博客 2009

JavaScript China城市联动

中国全城市的地址省,市,县 <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title></title> <script src="jquery.js"></script> <script src="json.js"></...

唯唯同学 2241

用Keil5给CH552G编程:手把手配置8051开发环境+LED闪烁实战

本文详细介绍了如何使用Keil5为CH552G单片机配置8051开发环境,并完成LED闪烁实战。从获取必要软件、安装WCH器件库到创建工程、编写程序及烧录,手把手指导开发者避开常见陷阱,特别适合从STC转向CH552G的开发者。

weixin_30733003的博客 538

敏捷软件开发之——软件坏味儿

      在软件开发的过程中,存在着两个级别的坏味。处于低级别的是代码坏味,在《重构-改善既有代码的设计》一书中给出了详细的说明与解决办法,这种坏味主要是指软件在代码实现中存在的。另外一种坏味是更高级别的,主要是指软件设计层面上的。下面就仔细介绍一下设计层面上的代码坏味。      首先给出问题,也就是都有哪些坏味,然后在剖析原因。软件坏味主要有:僵化性:很难对系统做出改动,因为每个

prince2270的专栏 942

SAP 关于WPS上传文件提示“文档中不包含数据“ 和“程序正在运行中“处理办法

最近这一周经常有用户反馈,使用WPS上传文件系统报错,一直提示“程序正在运行中”,另外在导入数据的时候提示"文档中不包含数据",跟进运维过程中遇到的这两种情况,分享一下处理的办法,如果各位更好的办法也可以给我留言分享。

我小时候很黑的博客 2846

【架构】C#重构常见方式详解:从代码坏味道到优雅设计的蜕变之路

在软件开发的生命周期中,代码重构如同房屋的定期修缮。根据《重构:改善既有代码的设计》(Martin Fowler)中的统计,约60%的软件成本发生在维护阶段。而C#作为企业级开发的主流语言,其代码质量直接影响着系统的可维护性和扩展性。记住这些数字:5分钟规则:发现坏味道立即重构30%原则:每次迭代留出30%时间用于重构童子军法则:离开时让代码比来时更干净正如Robert C. Martin在《代码整洁之道》中所说:“好的代码不是写出来的,而是改出来的。

杰西笔记 1242

【Py/Java/C++/C/JS/Go六种语言OD独家2024E卷真题】20天拿下华为OD笔试之【固定滑窗】2024E-考勤信息【欧弟算法】全网注释最详细分类最全的华为OD真题题解

可上练习华子OD、大厂真题绿色聊天软件戳oj1441了解算法冲刺训练(备注【优快云】否则不通过)

weixin_48157259的博客 618

【示波器专题】示波器探头的原理深入——有源探头之单端有源探头

由于接地环路的苛刻要求,更高带宽的单端有源探头就算设计了也不实用。因此单端有源探头的带宽一般在6GHz以内,更高带宽的信号测量也只能使用差分有源探头(市面上有些型号的差分探头可同时兼顾单端测试)。......

一点硬件 2145

软件管理中的坏味道

软件设计和编码中有坏味道,管理中一样存在坏味道,而且祸害更大。结合自己几年的工作经历,试着分享几种: 1)压迫式管理 市场的发展要求软件的交付速度要越来越快,而成本要不断降低。这是一种趋势。但软件开发的种种不确定性导致软件的交付通常需要比“期待的”要更多些时间。这确实一个规律。不过有的公司无视这个软件的开发规律,采用“期待”时间制定计划。比如通常需要半年完成的项...

weixin_34347651的博客 180

MaxScript批量修改材质、贴图名称

MaxScript批量修改材质、贴图名称1 实现效果1.1 修改前材质、贴图名称1.2 修改后2 代码 1 实现效果 1.1 修改前材质、贴图名称 1.2 修改后 2 代码 prefixName = "prefiname" maxFile = "maxfilepath" makeDir "newBitmappath" mapsPath = newbitmappath + "\\" fn formatStr index = ( str = index as string newS

郑德帅 3240

从坏味道到设计原则,构建灵活可维护的软件系统(《敏捷软件开发:原则、模式与实践》读书笔记)

1 单一职责原则 代码复杂性增加、难以复用、高耦合性、测试困难 提高可维护性、增强可复用性、降低耦合性、简化测试 增加类的数量、初始设计复杂性、管理和组织难度、潜在的性能开销。3 Liskov替换原则 程序不稳定、难以维护、降低复用性 提高代码的灵活性和复用性、增强系统的稳定性、简化代码维护 设计复杂性增加、可能需要更多的抽象、初始开发成本增加。5 接口隔离原则 臃肿的接口、难以维护、降低灵活性 提高灵活性、增强可维护性、提高代码的可理解性 增加设计复杂性、初始开发成本增加、可能的代码冗余。

weixin_55010563的博客 496

NOC总线架构拓扑介绍

在开篇里,我们对芯片PPA有了初步的认识。下面,让我们从访存这个简单的问题开始展开介绍芯片基础概念。CPU是怎样访问内存的?简单的答案是,CPU执行一条访存指令,把读写请求发往内存管理单元。内存管理单元进行虚实转换,把命令发往总线。总线把命令传递给内存控制器,内存控制器再次翻译地址,对相应内存颗粒进行存取。之后,读取的数据或者写入确认按照原路返回。再复杂些,当中插入多级缓存,在每一层缓存都未命中的情况下,访问才会最终达到内存颗粒。

元直的博客 5293

Camera2Demo

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

#软件配置管理#之坏味道搜集

软件开发热点词汇不断推陈出新,cmmi,agile,精益,持续交付,持续集成,灰度……但有一个词其实一直在那里,支持着各种各样的新热点,它是#软件配置管理#。 它也是影响团队软件开发效率的重大因素。下面来把我微博提到的坏味道归纳下#软件配置管理#之坏味道1:版本控制之下文件名里带版本号#软件配置管理#之坏味道2:通过评审或者发布的文件移到另外一个目录下,而不使用基线/lable/tag版本等等控制

高效软件开发 1988

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

开源软件的坏味道

前言 开源软件的世界,我们一直带着一颗敬畏之心来使用与学习,我们总觉得他们高高在上、他们完美无缺。但金无足赤,强如JDK、Spring也同样有这样或那样的问题。他们也并非那么遥不可及,我们也未必只配仰望,这里我们列举开源软件的那些“bad smell”,前车之鉴、后车之覆,开源软件也同样不完美。站在巨人肩膀上看到巨人的不完美,激励着我们往更成功的巨人之路...

weixin_33849215的博客 193

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

软件代码坏味道之滥用switch

switch是一种开关,是一种选择语句,用法简单,就是多分支选择语句,就是与多个if语句一样,功能上,switch与if两者可以完全可以相互取代,如果嵌套的if比较少时(三个以内),使用if比较简单,如果选择的分支比较多时,使用if会导致层数比较深,程序冗长,可读性下降;如果分支选择比较多,并且选择的类型码也比较固定的时候,可以使用switch来处理。...

代码充实生活的博客 1058

24种代码坏味道和重构手法

最近,小李感觉公司女生们看他的眼神不太对劲了,那种笑容好像是充满慈爱的、姨母般的笑容。作为一名老实本分的程序员,小李不太习惯这种被人过度关注的感觉,他不知道发生了什么。······小李和小王的关系似乎过于亲密,还经常挤在一个工位上办公,一直到半夜。这个流言直到某天他们的聊天内容被某个运营小姐姐听到,他们之间的秘密才被大家发现。

mxt51220的博客 1429

代码坏味道

代码坏味道原意是指代码中看起来让人不舒服的地方,需要依靠一个程序猿的直觉去判断,听起来是不是有点摸不着头脑?哈哈,其实也不用纠结,按照我的理解,代码坏味道其实也就是代码中不遵循代码规范的地方。那么,什么是写代码时要遵循的规范呢?我感觉主要有以下几种:1、无重复代码2、函数和功能模块仅实现单一功能目标3、隔离变化,集中修改4、信息隐藏和接口化大致有这么几种吧。下面我们具体看一下...

weixin_34360651的博客 104

软件工程9个测试坏味道

1、基本断言 基本断言应该表达某种假设或意图,它们应该声明代码的行为。基本断言的问题在于它缺乏意义,因为断言的基本原理和意图隐藏在看上去无意义的单词和数字背后,造成难以理解,并且难以验证断言的正确性。 改进方法: 要用被测功能的语言和词汇表达你的断言,每看到!=或==比拉符的断言,持别是涉及-1或0的数字时,就要考虑抽象层次是不星正确,如果断言不能立即显示出意义,就很可能是基本断言,需要重构...

Rnan_prince的博客 2175
上一篇: Ruby变量和常量
下一篇: Ruby方法
weeweee
博客等级 码龄16年 10粉丝 44原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值