我经常遇到必须执行大量检查的代码,并且在真正做任何事情之前最终会缩进至少五到六个级别.我想知道有什么替代方案.
下面我发布了一个我正在谈论的例子(这不是实际的生产代码,只是我想到的东西).
public String myFunc(SomeClass input) { Object output = null; 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) { //now actually do stuff! message = result_of_stuff_actually_done; } } } } } } return output; }
Galwegian.. 16
请参阅展平箭头代码以获取帮助.
用保护条款替换条件.
将条件块分解为单独的函数.
将否定支票转换为肯定支票.
ieure.. 8
提前退货:
if (input == null) { return output; }
OscarRyz.. 7
请永远不要那样编码(除非你维护自己的代码)
我不得不维护这样的代码,并且像Charles_Bronsonn电影一样糟糕(有些人喜欢那些电影)
这种代码通常来自程序语言,例如C(C程序:P)无论如何.
这就是ObjectOrientedProgrammng成为主流的原因.它允许您创建对象并向其添加状态.使用该状态创建操作.他们不仅是财产所有者.
我知道你编造了那个场景,但大多数时候所有这些条件都是商业规则!.大多数情况下,这些规则会更改,如果原始开发人员不再在那里(或者已经过了几个月),那么修改该代码将没有可行的方法.这些规则难以阅读.而且很多痛苦来自于此.
1.)使用私有成员变量(AKA属性,属性,实例变量等)保持对象的状态INSIDE对象
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 ( 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
通过保持规则变小,编码员可以很容易地理解它们而不是害怕刹车.
关于此更多内容可以在以下网址阅读:http://www.refactoring.com/
请参阅展平箭头代码以获取帮助.
用保护条款替换条件.
将条件块分解为单独的函数.
将否定支票转换为肯定支票.
提前退货:
if (input == null) { return output; }
请永远不要那样编码(除非你维护自己的代码)
我不得不维护这样的代码,并且像Charles_Bronsonn电影一样糟糕(有些人喜欢那些电影)
这种代码通常来自程序语言,例如C(C程序:P)无论如何.
这就是ObjectOrientedProgrammng成为主流的原因.它允许您创建对象并向其添加状态.使用该状态创建操作.他们不仅是财产所有者.
我知道你编造了那个场景,但大多数时候所有这些条件都是商业规则!.大多数情况下,这些规则会更改,如果原始开发人员不再在那里(或者已经过了几个月),那么修改该代码将没有可行的方法.这些规则难以阅读.而且很多痛苦来自于此.
1.)使用私有成员变量(AKA属性,属性,实例变量等)保持对象的状态INSIDE对象
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 ( 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
通过保持规则变小,编码员可以很容易地理解它们而不是害怕刹车.
关于此更多内容可以在以下网址阅读:http://www.refactoring.com/