ищем конкретный вариант использования, когда подклассу и классу в одном и том же пакете необходим доступ к защищенному полю или методу ...
Ну, для меня такой вариант использования является скорее общим, чем конкретным, и он вытекает из моих предпочтений:
- Начните с как можно более строгого модификатора доступа, прибегая к более слабому (-ым) модификатору (-ам) позже, если это будет сочтено необходимым.
- Имейте модульные тесты в том же пакете, что и проверенный код.
Сверху я могу начать проектирование для своих объектов с модификаторами доступа по умолчанию (я бы начал с этого, private
но это усложнило бы модульное тестирование):
public class Example {
public static void main(String [] args) {
new UnitTest().testDoSomething(new Unit1(), new Unit2());
}
static class Unit1 {
void doSomething() {} // default access
}
static class Unit2 {
void doSomething() {} // default access
}
static class UnitTest {
void testDoSomething(Unit1 unit1, Unit2 unit2) {
unit1.doSomething();
unit2.doSomething();
}
}
}
Примечание стороны в приведенном фрагменте, Unit1
, Unit2
и UnitTest
являются вложенными в Example
для простоты изложения, но в реальном проекте, я, скорее всего , эти классы в отдельных файлах (и UnitTest
даже в отдельном каталоге ).
Затем, когда возникнет необходимость, я бы ослабил контроль доступа по умолчанию protected
:
public class ExampleEvolved {
public static void main(String [] args) {
new UnitTest().testDoSomething(new Unit1(), new Unit2());
}
static class Unit1 {
protected void doSomething() {} // made protected
}
static class Unit2 {
protected void doSomething() {} // made protected
}
static class UnitTest {
// ---> no changes needed although UnitTest doesn't subclass
// ...and, hey, if I'd have to subclass... which one of Unit1, Unit2?
void testDoSomething(Unit1 unit1, Unit2 unit2) {
unit1.doSomething();
unit2.doSomething();
}
}
}
Видите ли, я могу сохранить код модульного теста ExampleEvolved
без изменений, поскольку защищенные методы доступны из одного пакета, даже если доступ к объекту не является подклассом .
Требуется меньше изменений => более безопасная модификация; В конце концов я изменил только модификаторы доступа и не изменил, какие методы Unit1.doSomething()
и что Unit2.doSomething()
делают, поэтому вполне естественно ожидать, что код модульного теста продолжит выполняться без изменений.
protected
только подкласс? Честно говоря, долгое время у меня было впечатление, что это поведение