OO软件设计中的7种坏味道,11种原则,23种模式

Programming.log:程序员的认知操作系统与结构化日志实践 编程日志不是简单的笔记归档,而是面向真实开发场景的认知建模工具。它基于语义锚定、管道推演、结构映射和异步时空折叠四大核心范式,将零散调试经验、错误现场和设计顿悟转化为可索引、可验证、可复现的知识单元。区别于通用笔记软件,Programming.log强调上下文绑定与语言无关的抽象自觉,例如用时间刻度重定义整数语义、以状态机编译器替代回调嵌套、通过DSL实现领域逻辑直译。其技术价值在于提升问题定位效率、降低团队认知负荷、支撑高可靠性系统演进,广泛适用于Java泛型擦除分析、Spring AOP调试、Kafka 阅读详情

一、7种设计坏味道

1.僵化性: 很难对系统进行改动,因为每个改动都会迫使许多对系统其他部分的其它改动。

2.脆弱性: 对系统的改动会导致系统中和改动的地方在概念上无关的许多地方出现问题。

3.牢固性: 很难解开系统的纠结,使之成为一些可在其他系统中重用的组件。

4.粘滞性: 做正确的事情比做错误的事情要困难。

5.复杂性(不必要的): 设计中包含有不具任何直接好处的基础结构。

6.重复性(不必要的): 设计中包含有重复的结构,而该重复的结构本可以使用单一的抽象进行统一。

7.晦涩性: 很难阅读、理解。没有很好地表现出意图。

二、11种原则 - Principle

类原则

1.单一职责原则 - Single Responsibility Principle(SRP)

就一个类而言,应该仅有一个引起它变化的原因。 职责即为“变化的原因”。

2.开放-封闭原则 - Open Close Principle(OCP)

软件实体(类、模块、函数等)应该是可以扩展的,但是不可修改。对于扩展是开放的,对于更改是封闭的. 关键是抽象.将一个功能的通用部分和实现细节部分清晰的分离开来。开发人员应该仅仅对程序中呈现出频繁变化的那些部分作出抽象. 拒绝不成熟的抽象和抽象本身一样重要 )

3.里氏替换原则 - Liskov Substitution Principle(LSP)

子类型(subclass)必须能够替换掉它们的基类型(superclass)。

4.依赖倒置原则(IoCP) 或 依赖注入原则 - Dependence Inversion Principle(DIP)

抽象不应该依赖于细节。细节应该依赖于抽象。Hollywood原则: "Don't call us, we'll call you". 程序中所有的依赖关系都应该终止于抽象类和接口。针对接口而非实现编程。任何变量都不应该持有一个指向具体类的指针或引用。任何类都不应该从具体类派生。 任何方法都不应该覆写他的任何基类中的已经实现了的方法。

5.接口隔离原则(ISP)

不应该强迫客户依赖于它们不用的方法。接口属于客户,不属于它所在的类层次结构。多个面向特定用户的接口胜于一个通用接口。

包内聚原则

6.重用发布等价原则(REP)

重用的粒度就是发布的粒度。

7.共同封闭原则(CCP)

包中的所有类对于同一类性质的变化应该是共同封闭的。 一个变化若对一个包产生影响, 则将对该包中的所有类产生影响, 而对于其他的包不造成任何影响。

8.共同重用原则(CRP)

一个包中的所有类应该是共同重用的。

如果重用了包中的一个类,

那么就要重用包中的所有类。

(相互之间没有紧密联系的类不应该在同一个包中。)

包耦合原则

9.无环依赖原则(ADP)

在包的依赖关系图中不允许存在环。

10.稳定依赖原则(SDP)

朝着稳定的方向进行依赖。

应该把封装系统高层设计的软件(比如抽象类)放进稳定的包中,不稳定的包中应该只包含那些很可能会改变的软件(比如具体类)。

11.稳定抽象原则(SAP)

包的抽象程度应该和其稳定程度一致。一个稳定的包应该也是抽象的,一个不稳定的包应该是抽象的. )

其它扩展原则

12.BBP(Black Box Principle)黑盒原则

多用类的聚合,少用类的继承。

13.DAP(Default Abstraction Principle)缺省抽象原则

在接口和实现接口的类之间引入一个抽象类,这个类实现了接口的大部分操作.

14.IDP(Interface Design Principle)接口设计原则

规划一个接口而不是实现一个接口。

15.DCSP(Don't Concrete Supperclass Principle)

  不要构造具体的超类原则,避免维护具体的超类。

16.迪米特法则

 一个类只依赖其触手可得的类。

三、23种设计模式( Pattern)

创建型

Abstract Factory(抽象工厂模式) -> (简单工厂模式)

Factory Method(工厂模式)

Builder(生成器模式)

Singleton(单件模式) -> (多例模式)

Prototype(原型模式)

结构型

Adapter(适配器模式)

Bridge(桥接模式)

Composite(组合模式)

Decorator(装饰模式)

Facade(外观模式,门面模式)

Flyweight(享元模式) -> (不变模式)

Proxy(代理模式)

行为型

Chain of Responsibility(职责链模式)

Command(命令模式)

Interpreter(解释器模式)

Iteartor(迭代器模式)

Mediator(中介者模式)

Memento(备忘录模式)

Observer(观察者模式)

State(状态模式)

Strategy(策略模式)

TemplateMethod(模板方法模式)

Visitor(访问者模式)

2. Netty使用JSerialComm进行串口读取(二) 现在开始处理这些问题 第一个问题:串口读取超时异常一路传播到最后也没有处理。 ​ 第二个问题:即使处理了该异常,程序仍然退出,这不能满足一些实际使用要求需求。该问题与设置很长的读取超时时间没关系,无论多长到时间后总会退出。 阅读详情

相关推荐

基于IC动态加权的机器学习多因子选股策略:从模型融合到实战回测

在量化投资领域,多因子选股模型通过挖掘市场数据中的有效信号来预测股票收益。其核心原理在于利用统计学与机器学习算法,从海量因子中识别出与未来收益具有稳定相关性的特征。这一技术的核心价值在于将主观投资决策转化为系统化、可重复的客观过程,从而在控制风险的前提下追求超额收益。其典型应用场景包括股票阿尔法策略构建、Smart Beta产品设计以及资产配置中的股票筛选环节。本文聚焦于如何通过信息系数(IC)这一关键指标,动态融合Ridge回归、MLP神经网络和随机森林等多个预测模型,构建一个能够自适应市场风格轮动的选股

weixin_34216614的博客 451

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

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

梁飞的博客 2496

三相逆变器拓扑结构的分析及应用场景

三相逆变器是电力电子领域中广泛应用的一种设备,用于将直流电转换为交流电。不同的拓扑结构在性能、成本、复杂度和应用领域上存在差异。小编将在本文中将进一步拓展对三相逆变器拓扑结构的分析,并探讨其适用的应用场景。

道合顺的博客 2237

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

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

prince2270的专栏 942

车载通信技术原理-CAN通讯和代码配置:奥迪A6轿车总线拓扑图

CAN总线是一种用于汽车监测与控制系统的串行通信协议,由德国Bosch公司开发。它具有多主工作方式、优先级仲裁、高抗干扰等特点,支持点对点、广播等多种通信方式,传输距离可达10公里。CAN协议采用差分信号传输,物理层使用双绞线,数据链路层实现错误检测、位填充等功能。协议帧类型包括数据帧、遥控帧、错误帧等。CAN总线自1986年发布以来,已成为汽车电子系统的标准配置,广泛应用于车载网络。文章还提供了S32K144芯片的CAN驱动代码示例。

擎天柱工坊 1067

Kubernetes集群环境搭建与初始化

Kubernetes是Google开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。在生产环境中部署一个应用程序时,通常要部署该应用的多个实例以便对应用请求进行负载均衡。在Kubernetes中,我们可以创建多个容器,每个容器里面运行一个应用实例,然后通过内置的负载均衡策略,实现对这一组应用实例的管理、发现、访问,而这些细节都不需要运维人员去进行复杂的手工配置和处理。

m0_75254642的博客 1525

对软件代码坏味道的认识

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

代码充实生活的博客 2009

php环境如何实现国密SM2相关功能

🏆本文收录于《优快云问答解惑-专业版》专栏,主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!

**My Coding Family** 1616

《重构 改善既有代码的设计》之代码的坏味道

1 简介 知道“如何”不代表知道”何时”。决定何时重构、何时停止和知道重构机制如何运转一样重要。 从我们的经验来看,没有任何量度规矩比得上一个见识广博者的直觉。我们智慧告诉你一些迹象,它会指出“这里有一个可以用重构解决的问题”。你必须培养出自己的判断力,学会判断一个类内有多少实例变量算是太大,一个函数内有多少代码才算太长。 2 坏味道列表 2.1 重复代码Duplicated Code 如果你在...

不当初 1561

PCL点云算法与项目实战案例汇总(长期更新)

本专栏将深入探讨PCL(点云库)的基础算法,旨在帮助读者掌握点云处理的核心技术。内容涵盖点云的采样、过滤、配准、分割等基础操作,并结合实际案例,展示这些算法在工程中的应用。无论你是初学者还是有一定经验的开发者,都能通过本专栏加深对PCL的理解,提升在三维数据处理领域的技能。

纵马踏花向自由 3007

威纶通触摸屏与S7-1200以太网通信的具体方法和步骤(非常详细)

威纶通触摸屏与S7-1200以太网通信的具体方法和步骤(非常详细)

Robot_PLC_HMI_Automation 1万+

《重构改善既有代码的设计》——代码的坏味道

这本书虽然主要是讲重构,但是对于经验浅的程序员来说,编写程序的规范和技巧更值得借鉴。 代码的坏味道,对应的是好的编程习惯。本文中方法(Java)=函数(python),通用技巧总结如下。 1. 处理重复代码 从重复代码中抽象出独立功能函数,或者超类。 2. 拆解过长函数 程序越长越难理解,对过长函数进行拆解,给每个小函数命名。让小函数容易理解的关键在于,有一个一眼就能判断功能的名字。

小白兔的窝 1336

Vue - 简约大气 404 页面

效果图 实现代码 复制即可。 <template> <div> <div class="error"> <!-- 图片可保存到本地 --> <img src="https://img-blog.csdnimg.cn/20210715111039922.png"> <p>抱歉!你访问的页面不存在或已删除 :( </p> <span class="back" @click="go(

🏆 前端领域优质创作者 3371

实测9类情绪识别准确率!Emotion2Vec+ Large性能表现分享

本文介绍了如何在星图GPU平台上自动化部署Emotion2Vec+ Large语音情感识别系统 二次开发构建by科哥镜像,实现高精度9类情绪(如愤怒、快乐、悲伤等)实时识别,典型应用于客服语音质检与情绪转折点定位,显著提升服务体验分析效率。

weixin_42298778的博客 357

WINCC7.3破解文件

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

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

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

python3 核心笔记

本文主要是针对python3的一些核心要点做一些记录,感兴趣的可以关注和订阅。会持续更新,这个玩意学习一下,可以为数据分析和AI打下一定的基础。

yanghuashuiyue的专栏 620

深度学习工具包 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")

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

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

杰西笔记 1242

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

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

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

高效软件开发 1988

重构 改善既有代码的设计——代码的坏味道

了解并熟练重构的机制,并不代表我们知道何时应该重构;前者可以从书中学习到,但是何时应该重构就是一个实践问题,需要我们 培养自己的判断力,知道何时何处如何重构; 1.Duplicated Code(重复代码) A.同一个类中不同方法包含相同的表达式:把相同的表达式提炼成一个方法,在包含表达式的地方直接调用该方法; B.互为兄弟的类包含相同的表达式:把相同的表达式提炼成一个方法,并放到基类中;

Chaos的专栏 2246

三、代码的坏味道

1、Duplicated Code(重复代码) 如果你在一个以上的地点看到相同的程序结构,那么可以肯定:设法将它们合而为一,程序会变得更好。 2、Long Method(过长函数) (1)“”间接层“”所能带来的全部利益--解释能力、共享能力、选择能力--都是由小型函数支持的。 (2)可以遵循这样一条原则:每当感觉需要以注释来说明点什么的时候,我们就把需要说明的东西写进一个独立函数中,并以

whycold的专栏 746

App版本更新接口的设计

工作这几年碰到的版本检测升级的接口也算是五花八门,啥样的都有,但肯定有的功能是有个apk的下载链接,能间接或直接提示你是强制还是非强制更新:- 间接是指提供你后台最新版本号,让你自己与本地版本号通过比较得出是否升级;- 直接就是后台接口直接返回个Boolean类型告诉你是强制或者非强制更新。个人认为一个好的版本检测接口需要设计的更灵活更清晰用起来更方便,下面就我理解的接口设计如下(如思路有误,欢迎...

初来乍到 6096

软件的坏味道

1) Duplicated Code(重复代码) 2) Long Method(过长函数) 3) Large Class(过大类) 4) Long Parameter List(过长参数列) 5) Divergent Change(发散式变化)——过耦合 6) Shotgun Surgery(散弹式修改)——过度的分散与过耦合相反 7) Feature Envy(依恋情节)

老睿的专栏 881

【软件体系结构】软件体系结构笔记

软件体系结构课堂笔记

passnight的博客 5802

软件管理中的坏味道

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

weixin_34347651的博客 180

21种代码的“坏味道”

1.Duplicated Code代码重复几乎是最常见的异味了。他也是Refactoring 的主要目标之一。代码重复往往来自于copy-and-paste 的编程风格。与他相对应OAOO 是一个好系统的重要标志(请参见我的duplicated code 一文:http://www.erptao.org/download.php?op=viewsdownload&sid=6)。2.Long m

透明思考@优快云 3062

从架构可视化入门到抽象坏味道

C4不能帮你做好架构设计,但是它能暴露出你设计中的问题,以便于被自己或其他人纠正。可视化的威力就在这里,但根据我的经验,即便你用上了C4也不见得就能表达清楚,不过好消息是,我们终于可以聊一些高级的表达问题了。

IDEAL Garden 499

开源软件的坏味道

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

weixin_33849215的博客 193
上一篇: Overload和Override的区别
下一篇: tomcat 配置实现http跳转至https
伟克
博客等级 码龄18年 16粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值