Мы обсуждаем с другом дизайн и эффективность кода Java.
Он утверждает, что методы предпочтительно должны быть закрытыми по соображениям производительности, а также для защиты согласованности классов при переопределении.
Я утверждаю, что методы предпочтительно должны быть защищены для полной настраиваемости и во избежание потери времени на изменение и выпуск API, как только его пользователь захочет изменить часть его поведения.
Мы знаем, что композиция предпочтительнее наследования так что здесь я в основном фокусируюсь на сравнении производительности.
Простой тест (см. ниже) доказывает, что расширенные классы с родителем, имеющим защищенные методы, не медленнее, чем классы с родителем, имеющим частные методы. Это даже иногда (я не очень понимаю изменение производительности) быстрее.
elapsed:8051733.063 microseconds for A (private)
elapsed:8036953.805 microseconds for B (protected)
Считаете ли вы, что приведенный ниже тест достаточно надежен для проведения сравнения?
public class VerifPerfProtected {
public static void main(String[] args) {
int ncalls = 1000000000; //10^9
ChildrenClassA a = new ChildrenClassA();
ChildrenClassB b = new ChildrenClassB();
long start = System.nanoTime();
a.manyCalls(ncalls);
long stop = System.nanoTime();
System.out.println("elapsed:" + (stop - start)/1000.0 + " microseconds for A (private)");
start = System.nanoTime();
b.manyCalls(ncalls);
stop = System.nanoTime();
System.out.println("elapsed:" + (stop - start)/1000.0 + " microseconds for B (protected)");
}
public static class ParentClassA{
public void manyCalls(int n){
for (int i = 0; i < n; i++) {
callAmethod();
}
}
public void callAmethod(){
aPrivateMethod();
}
private void aPrivateMethod(){
int a=0;
for (int i = 0; i < 5; i++) {
a++;
}
}
}
public static class ParentClassB{
public void manyCalls(int n){
for (int i = 0; i < n; i++) {
callAmethod();
}
}
public void callAmethod(){
aProtectedMethod();
}
protected void aProtectedMethod(){
int a=0;
for (int i = 0; i < 5; i++) {
a++;
}
}
}
public static class ChildrenClassA extends ParentClassA{
}
public static class ChildrenClassB extends ParentClassB{
}
}