Language agnostic 是否有超缩进代码的替代方案?
我经常遇到需要执行大量检查的代码,在真正执行任何操作之前,代码至少会缩进五到六级。我想知道还有什么选择 下面我发布了一个我正在谈论的示例(它不是实际的生产代码,只是我头脑中突然想到的东西)Language agnostic 是否有超缩进代码的替代方案?,language-agnostic,coding-style,indentation,Language Agnostic,Coding Style,Indentation,我经常遇到需要执行大量检查的代码,在真正执行任何操作之前,代码至少会缩进五到六级。我想知道还有什么选择 下面我发布了一个我正在谈论的示例(它不是实际的生产代码,只是我头脑中突然想到的东西) 公共字符串myFunc(SomeClass输入) { 对象输出=null; 如果(输入!=null) { SomeClass2 obj2=input.getSomeClass2(); 如果(obj2!=null) { SomeClass3 obj3=obj2.getSomeClass3(); if(obj3!
公共字符串myFunc(SomeClass输入)
{
对象输出=null;
如果(输入!=null)
{
SomeClass2 obj2=input.getSomeClass2();
如果(obj2!=null)
{
SomeClass3 obj3=obj2.getSomeClass3();
if(obj3!=null&&!BAD_OBJECT.equals(obj3.getSomeProperty())
{
SomeClass4=obj3.getSomeClass4();
如果(obj4!=null)
{
int myVal=obj4.getSomeValue();
如果(错误值!=myVal)
{
String message=this.getMessage(myVal);
如果(最小值,请参阅以获取帮助
用防护罩替换条件
条款
将条件块分解为
分离功能
将否定支票转换为
阳性检查
提早返回:
if (input == null) {
return output;
}
您可以通过使用保护子句来消除一些嵌套
public String myFunc(SomeClass input)
{
Object output = null;
if(input == null) return "";
SomeClass2 obj2 = input.getSomeClass2();
if(obj2 == null) return "";
SomeClass3 obj3 = obj2.getSomeClass3();
if(obj3 == null || BAD_OBJECT.equals(obj3.getSomeProperty()))
{
return "";
}
SomeClass4 = obj3.getSomeClass4();
if(obj4 == null) return "";
int myVal = obj4.getSomeValue();
if(BAD_VALUE == myVal) return "";
String message = this.getMessage(myVal);
if(MIN_VALUE <= message.length() &&
message.length() <= MAX_VALUE)
{
//now actually do stuff!
message = result_of_stuff_actually_done;
}
return output;
}
公共字符串myFunc(SomeClass输入)
{
对象输出=null;
如果(输入==null)返回“”;
SomeClass2 obj2=input.getSomeClass2();
如果(obj2==null)返回“”;
SomeClass3 obj3=obj2.getSomeClass3();
如果(obj3==null | | BAD_OBJECT.equals)(obj3.getSomeProperty())
{
返回“”;
}
SomeClass4=obj3.getSomeClass4();
如果(obj4==null)返回“”;
int myVal=obj4.getSomeValue();
如果(BAD_VALUE==myVal)返回“”;
String message=this.getMessage(myVal);
如果(MIN_值是,您可以按如下方式删除缩进:
基本上是按顺序进行检查,并与失败而不是成功进行比较。
它消除了嵌套并使其更易于遵循(IMO)
公共字符串myFunc(SomeClass输入)
{
对象输出=null;
如果(输入==null)
{
返回null;
}
SomeClass2 obj2=input.getSomeClass2();
如果(obj2==null)
{
返回null;
}
SomeClass3 obj3=obj2.getSomeClass3();
如果(obj3==null | | BAD_OBJECT.equals)(obj3.getSomeProperty())
{
返回null;
}
SomeClass4=obj3.getSomeClass4();
if(obj4==null)
{
返回null;
}
int myVal=obj4.getSomeValue();
如果(坏值==myVal)
{
返回null;
}
String message=this.getMessage(myVal);
如果(MIN_值如果不需要处理停止,则不嵌入
例如,您可以执行以下操作:
if(input == null && input.getSomeClass2() == null && ...)
return null;
// Do what you want.
假设您使用的是像Java这样的语言,它对条件进行排序
或者,您可以:
if(input == null && input.getSomeClass2() == null)
return null;
SomeClass2 obj2 = input.getSomeClass2();
if(obj2 == null)
return null;
...
// Do what you want.
对于更复杂的情况
如果不需要处理,可以从方法返回。嵌入大型嵌套if几乎不可能读取。如果只是可读性问题,可以通过将嵌套移动到另一个方法使其更清晰。如果愿意,还可以转换为保护样式
public String myFunc(SomeClass input)
{
Object output = null;
if (inputIsValid(input))
{
//now actually do stuff!
message = result_of_stuff_actually_done;
}
return output;
}
private bool inputIsValid(SomeClass input)
{
// *****************************************
// convert these to guard style if you like
// *****************************************
if(input != null)
{
SomeClass2 obj2 = input.getSomeClass2();
if(obj2 != null)
{
SomeClass3 obj3 = obj2.getSomeClass3();
if(obj3 != null && !BAD_OBJECT.equals(obj3.getSomeProperty()))
{
SomeClass4 = obj3.getSomeClass4();
if(obj4 != null)
{
int myVal = obj4.getSomeValue();
if(BAD_VALUE != myVal)
{
String message = this.getMessage(myVal);
if(MIN_VALUE <= message.length() &&
message.length() <= MAX_VALUE)
{
return true;
}
}
}
}
}
}
return false;
}
公共字符串myFunc(SomeClass输入)
{
对象输出=null;
if(输入有效(输入))
{
//现在真的做点什么!
消息=实际完成的工作的结果;
}
返回输出;
}
私有布尔输入有效(SomeClass输入)
{
// *****************************************
//如果愿意,可以将其转换为防护样式
// *****************************************
如果(输入!=null)
{
SomeClass2 obj2=input.getSomeClass2();
如果(obj2!=null)
{
SomeClass3 obj3=obj2.getSomeClass3();
if(obj3!=null&&!BAD_OBJECT.equals(obj3.getSomeProperty())
{
SomeClass4=obj3.getSomeClass4();
如果(obj4!=null)
{
int myVal=obj4.getSomeValue();
如果(错误值!=myVal)
{
String message=this.getMessage(myVal);
如果(最小值)为“是”,则存在替代方案。
请不要这样编写代码(除非您维护自己的代码)
我不得不维护这样的代码,就像查尔斯·布朗森的电影一样糟糕(尽管有些人喜欢这些电影)
这种代码通常来自过程语言,比如C(is C procedural:p)
这就是ObjectOrientedProgrammng成为主流的原因。它允许您创建对象并向其添加状态。使用该状态创建操作。他们不仅仅是属性持有者
我知道是你编造的,但大多数情况下,所有这些条件都是业务规则!!。大多数情况下,这些规则都会改变,如果原始开发人员不再在那里(或者几个月过去了)没有一种可行的方法来修改代码。规则很难阅读。这会带来很多痛苦
你能做什么?
1.)使用private成员变量(又名属性、属性、实例变量等)将对象的状态保持在对象内部
2.)将方法设置为私有(这就是访问级别的作用),这样就不会有人错误地调用它们,并将程序置于NullPointerException区域
3.)创建定义条件的方法。这就是他们所谓的自文档代码
所以不是
// validates the user has amount
if( amount > other && that != var || startsAligned() != false ) {
}
创建一个方法
if( isValidAmount() ) {
}
private boolean isValidAmount() {
return ( amount > other && that != var || startsAligned() != false );
}
我知道它看起来很冗长,但允许人们阅读代码。编译器不关心可读性
那么,使用这种方法,您的超嵌套结构会是什么样子呢
像这样
// these are business rules
// then it should be clear that those rules are
// and what they do.
// internal state of the object.
private SomeClass2 obj2;
private SomeClass3 obj3;
private SomeClass4 obj4;
//public String myFunc( SomeClass input ) {
public String myComplicatedValidation( SomeClass input ) {
this.input = input;
if ( isValidInput() &&
isRuleTwoReady() &&
isRuleTreeDifferentOf( BAD_OBJECT ) &&
isRuleFourDifferentOf( BAD_VALUE ) &&
isMessageLengthInRenge( MIN_VALUE , MAX_VALUE ) ) {
message = resultOfStuffActuallyDone();
}
}
// These method names are self explaining what they do.
private final boolean isValidInput() {
return this.input != null;
}
private final boolean isRuleTwoReady() {
obj2 = input.getSomeClass2();
return obj2 != null ;
}
private final boolean isRuleTreeDifferentOf( Object badObject ) {
obj3 = obj2.getSomeClass3();
return obj3 != null && !badObject.equals( obj3.getSomeProperty() );
}
private final boolean isRuleFourDifferentOf( int badValue ) {
obj4 = obj3.getSomeClass4();
return obj4 != null && obj4.getSomeValue() != badValue;
}
private final boolean isMessageLengthInRenge( int min, int max ) {
String message = getMessage( obj4.getSomeValue() );
int length = message.length();
return length >= min && length <= max;
}
几乎可以理解为
if is valid input
and rule two is ready
and rule three is not BAD OBJECT
and rule four is no BAD_VALUE
and the message length is in range
通过保持规则的小范围变化,编码人员可以非常容易地理解它们,而不必害怕某些事情
很多
// these are business rules
// then it should be clear that those rules are
// and what they do.
// internal state of the object.
private SomeClass2 obj2;
private SomeClass3 obj3;
private SomeClass4 obj4;
//public String myFunc( SomeClass input ) {
public String myComplicatedValidation( SomeClass input ) {
this.input = input;
if ( isValidInput() &&
isRuleTwoReady() &&
isRuleTreeDifferentOf( BAD_OBJECT ) &&
isRuleFourDifferentOf( BAD_VALUE ) &&
isMessageLengthInRenge( MIN_VALUE , MAX_VALUE ) ) {
message = resultOfStuffActuallyDone();
}
}
// These method names are self explaining what they do.
private final boolean isValidInput() {
return this.input != null;
}
private final boolean isRuleTwoReady() {
obj2 = input.getSomeClass2();
return obj2 != null ;
}
private final boolean isRuleTreeDifferentOf( Object badObject ) {
obj3 = obj2.getSomeClass3();
return obj3 != null && !badObject.equals( obj3.getSomeProperty() );
}
private final boolean isRuleFourDifferentOf( int badValue ) {
obj4 = obj3.getSomeClass4();
return obj4 != null && obj4.getSomeValue() != badValue;
}
private final boolean isMessageLengthInRenge( int min, int max ) {
String message = getMessage( obj4.getSomeValue() );
int length = message.length();
return length >= min && length <= max;
}
if ( isValidInput() &&
isRuleTwoReady() &&
isRuleTreeDifferentOf( BAD_OBJECT ) &&
isRuleFourDifferentOf( BAD_VALUE ) &&
isMessageLengthInRenge( MIN_VALUE , MAX_VALUE ) ) {
message = resultOfStuffActuallyDone();
}
if is valid input
and rule two is ready
and rule three is not BAD OBJECT
and rule four is no BAD_VALUE
and the message length is in range