Java封装和OOP最佳实践

mow*_*nay 2 java oop encapsulation

我实现了一个名为mobileCall的类.我从这个类创建了几个对象,并使用来自XML的值填充此对象的String变量,该XML具有针对特定人员的多个mobileCall.我需要对这个人拨打的所有电话进行分组和统计(即国内电话:11分钟;国际电话:15分钟;数据:20 MB)

因此,我在类中实现了几个公共方法来检查调用的类型以返回true或false.在主要类中,我调用这些方法来检查它们是否满足标准我计算特定计数器.

有人专业看过我的代码并说这不是一个好习惯,而OOP旨在消除这种"你是什么"的方法.而且有更好的方法来实现这种行为.我试图阅读OOP和封装,但无法找到更好的方法来做到这一点.我觉得他有一点意义.

代码示例

public class MobileCall {

    String callType;
    String callDuration;
    String callAmount;
    String callerID;
    String calleID;
    ....
    public boolean isNational(){

        if (callType.compareTo("National")==0)
            return true;
        else
            return false;
    }

    public boolean isInternational(){

        if (callType.compareTo("international")==0)
            return true;
        else
            return false;
    }
    ...
}

In Main Method

int nationalCounter;
int internationalCounter;
MobileCall mobileCall = new MobileCall();

if(mobileCall.isNational())
    nationalCounter = nationalCounter + mobileCall.getCallDuration();
else if (mobileCall.isInternational())
    internationalCounter = internationalCounter + mobileCall.getDuration();
....
Run Code Online (Sandbox Code Playgroud)

Edw*_*uck 5

private String callType;

....
public boolean isNational(){

    if (callType.compareTo("National")==0)
        return true;
    else
        return false;
}

public boolean isInternational(){

    if (callType.compareTo("international")==0)
        return true;
    else
        return false;
}
Run Code Online (Sandbox Code Playgroud)

是相关的代码.这就是重点(现在callType已经强烈封装了).

三个月后,有人抱怨该程序占用了太多内存.你重新审视你的代码,并确定字符串不是确定电话国籍的最佳方式,毕竟它是国际的还是不是,对吧?这意味着您最多需要一位来存储数据.

你做出改变

private boolean nationalCall;
Run Code Online (Sandbox Code Playgroud)

然后更改使用此数据的方法

public boolean isNational() {
  return nationalCall;
}

public boolean isInternational() {
  return !nationalCall;
}
Run Code Online (Sandbox Code Playgroud)

而且由于您正确封装了"国家呼叫数据",您可以放心,您不再需要寻找其余程序以确保程序中的其他位可以正常工作.变化的"效果"被"封装"在类的"接口"的"边界",这实际上是由许多"成员方法"实现的.

现在代码就像这样

if (mobileCall.isNational()) {
    nationalCounter = nationalCounter + mobileCall.getCallDuration();
} else if (mobileCall.isInternational()) {
    internationalCounter = internationalCounter + mobileCall.getDuration();
}
Run Code Online (Sandbox Code Playgroud)

看起来很可疑.请注意,这段代码似乎非常关注不同类的数据和方法.也许外部管理班级到这样的程度,以至于行为的位置错位了?

如果您将方法添加到"调用"类

public int getNationalMinutes() {
  if (national) {
    return callDuration;
  }
  return 0;
}

public int getInternationalMinutes() {
  if (!national) {
    return callDuration;
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后你可以减少你的累积代码

while (Call call : client.getAllCalls()) {
  internationalMinutes += call.getInternationalMinutes();
  nationalMinutes += call.getNationalMinutes();
}
Run Code Online (Sandbox Code Playgroud)

请注意,最后一点工作不是严格数据意义上的100%封装,因为我们添加了接口项(方法); 但它确实在行为意义上做了一些封装,因为我们不再需要根据一系列查询来确定呼叫分钟是国际的还是国家的,以确定类的内部状态.

对类进行的一系列检查以确定如何使用类的日期是"Call"类之外的行为的外部迁移.因此,将此行为移回到类中可能被视为对类行为的封装,与之前的示例不同,后者是对类的数据的严格封装.

很多时候,人们忘记了类封装了数据行为.感谢您找到一个很好的例子,其中两个封装点都可以在同一个问题中呈现.