Контекст:
Я Java-программист и читаю Uncle Bob Agile Software Development.Что касается принципа сегрегации интерфейса ISP, то здесь приводится аргумент, который я понимаю как:
Позволяет:
interface Service {
function doA();
}
class ServiceImpl implements Service {...}
class ServiceClient {
// ServiceImpl is injected; eg either through constructor or setter
private Service service;
function useOnlyDoA() {
service.doA();
}
}
И теперь, если служба интерфейса изменяется, например, добавляется метод doB()
, тогдавсе зависимые классы, например, ServiceClient
, должны быть перекомпилированы, даже если они не используют добавленный метод!(действительно ??)
- Верно ли это для Java?
- Верно ли это для c ++?
- Для каких других языков это верно, а для каких нет?'t?
Я был убежден, что в отношении Java, если ServiceClient
в пакете, например, client.jar
, интерфейс Service
в service.jar
и ServiceImpl
в impl.jar
, затем client.jar
не нужно перекомпилировать и перекомпилировать, если он не использует новые методы из интерфейса службы и может использоваться вместе с новыми версиями service.jar
и impl.jar
.Мне кажется, что дела обстоят именно так в Java.Это что-то другое, например, в c ++ или некоторых других языках?
Возможно, в c ++ гораздо больше проблем, например, https://stackoverflow.com/a/4033900/1423685
Чтобы было ясно:
Я незапрос о перекомпиляции класса, реализующего измененный интерфейс (это очевидно, класс должен реализовать новый добавленный метод).Но я спрашиваю, должен ли я перекомпилировать класс ServiceClient, который использует этот интерфейс, даже когда класс не использует новые добавленные методы.Возможно в c ++ BC изменения и клиент действительно должен быть перекомпилирован, но мне кажется, что не в java.
Edit:
Я реализовал тест в java.4 банки:
- interface.jar - содержит интерфейс
public interface Service
- creation.jar - содержит
public class ServiceImpl implements Service
- две вышеупомянутые банки заменяют
- два приведенных ниже jar-файла не изменились даже после изменения выше
- interfaceclient.jar - зависит от interface.jar, содержит класс
ClientOfService
, принимая Service
в качестве параметра конструктора, использует этот сервис в doA()
method - application.jar - зависит от всех вышеуказанных jar-файлов.Класс App в методе main создает экземпляр ServiceImpl и передает его в качестве аргумента конструктору ClientOfService, затем вызывает метод на ClientOfService, который выполняет вызов метода doA () из Service:
public static void main(String[] args) {
Service service = new ServiceImpl();
ClientOfService clientOfService = new ClientOfService(service);
System.out.println("App.main() :: calling clientOfService.doWorkCallingDoAFromService");
clientOfService.doWorkCallingDoAFromService();
System.out.println("App.main() :: end of main");
}
Основное приложение запускается успешно после изменения interface.jar и creation.jar (я добавил несколько неиспользуемых методов и удалил один старый метод).
Таким образом, задача состоит в том, как изменить интерфейс (конечно, без изменения doA()
объявление метода) и реализация, чтобы остановить его успешную работу?Является ли это возможным?Если так, то как?