Kip*_*Kip 8 language-agnostic coding-style indentation
我经常遇到必须执行大量检查的代码,并且在真正做任何事情之前最终会缩进至少五到六个级别.我想知道有什么替代方案.
下面我发布了一个我正在谈论的例子(这不是实际的生产代码,只是我想到的东西).
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;
}
Run Code Online (Sandbox Code Playgroud)
请永远不要那样编码(除非你维护自己的代码)
我不得不维护这样的代码,并且像Charles_Bronsonn电影一样糟糕(有些人喜欢那些电影)
这种代码通常来自程序语言,例如C(C程序:P)无论如何.
这就是ObjectOrientedProgrammng成为主流的原因.它允许您创建对象并向其添加状态.使用该状态创建操作.他们不仅是财产所有者.
我知道你编造了那个场景,但大多数时候所有这些条件都是商业规则!.大多数情况下,这些规则会更改,如果原始开发人员不再在那里(或者已经过了几个月),那么修改该代码将没有可行的方法.这些规则难以阅读.而且很多痛苦来自于此.
1.)使用私有成员变量(AKA属性,属性,实例变量等)保持对象的状态INSIDE对象
2.)使方法成为私有(这是访问级别的用途),因此没有人可以错误地调用它们并将程序放在NullPointerException域中.
3.)创建定义条件的方法.这就是他们所谓的自我记录代码
而不是
// validates the user has amount
if( amount > other && that != var || startsAligned() != false ) {
}
Run Code Online (Sandbox Code Playgroud)
创建一个方法
if( isValidAmount() ) {
}
private boolean isValidAmount() {
return ( amount > other && that != var || startsAligned() != false );
}
Run Code Online (Sandbox Code Playgroud)
我知道它看起来很冗长,但允许人类阅读代码.编译器不关心可读性.
那么你用这种方法看起来会怎么样呢?
像这样.
// 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;
}
Run Code Online (Sandbox Code Playgroud)
我知道,看起来更像编码.但想想这个.规则几乎是人类可读的
if ( isValidInput() &&
isRuleTwoReady() &&
isRuleTreeDifferentOf( BAD_OBJECT ) &&
isRuleFourDifferentOf( BAD_VALUE ) &&
isMessageLengthInRenge( MIN_VALUE , MAX_VALUE ) ) {
message = resultOfStuffActuallyDone();
}
Run Code Online (Sandbox Code Playgroud)
可能几乎被解读为
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
Run Code Online (Sandbox Code Playgroud)
通过保持规则变小,编码员可以很容易地理解它们而不是害怕刹车.
关于此更多内容可以在以下网址阅读:http://www.refactoring.com/