LINUX.ORG.RU

История изменений

Исправление Manhunt, (текущая версия) :

Функции, которые используют базовый тип, должны иметь возможность использовать подтипы базового типа, не зная об этом.

Опять же наследование отсутствует, и этот принцип не имеет смысла.

Заблуждение. Liskov substitution нужно иметь ввиду всякий раз, как ты реализуешь какой-либо трейт. Дело в том, что контракт, на который полагаются клиенты этого трейта, включает в себя (помимо сигнатур методов) ещё и определенное поведение этих методов. Скажем, если ты у некоего контейнера вызвал метод Clear(), то ты ожидаешь, что последующий вызов метода IsEmpty() вернет True (в однопоточной программе). Реализация контейнера должна не только предоставлять методы Clear() и IsEmpty() с подходящими сигнатурами, но и обеспечивать соответствующее поведение. Liskov substitution — именно об этом.

К сожалению, известные мне мейнстримные языки (и Rust, увы, тоже) не позволяют формально специфицировать поведенческую часть контракта, поэтому приходится фиксировать ее в юнит-тестах. Убого и ненадежно, ну да видно для лучших инструментов время еще не пришло. Baby steps.

Исправление Manhunt, :

Функции, которые используют базовый тип, должны иметь возможность использовать подтипы базового типа, не зная об этом.

Опять же наследование отсутствует, и этот принцип не имеет смысла.

Заблуждение. Liskov substitution нужно иметь ввиду всякий раз, как ты реализуешь какой-либо трейт. Дело в том, что контракт, на который полагаются клиенты этого трейта, включает в себя (помимо сигнатур методов) ещё и определенное поведение этих методов. Скажем, если ты у некоего контейнера вызвал метод Clear(), то ты ожидаешь, что последующий вызов метода IsEmpty() вернет True (в однопоточной программе). Реализация контейнера должна не только предоставлять методы Clear() и IsEmpty() с подходящими сигнатурами, но и обеспечивать соответствующее поведение. Liskov substitution — именно об этом.

К сожалению, известные мне мейнстримные языки (и Rust, увы, тоже) не позволяют формально специфицировать поведенческую часть контракта, и приходится фиксировать ее в юнит-тестах. Убого и ненадежно, ну да видно для лучших инструментов время еще не пришло. Baby steps.

Исправление Manhunt, :

Функции, которые используют базовый тип, должны иметь возможность использовать подтипы базового типа, не зная об этом.

Опять же наследование отсутствует, и этот принцип не имеет смысла.

Заблуждение. Liskov substitution нужно иметь ввиду всякий раз, как ты реализуешь какой-либо трейт. Дело в том, что контракт, на который полагаются клиенты этого трейта, включает в себя (помимо сигнатур методов) ещё и определенное поведение этих методов. Скажем, если ты у некоего контейнера вызвал метод Clear(), то ты ожидаешь, что последующий вызов метода IsEmpty() вернет True (в однопоточной программе). Реализация контейнера должна не только предоставлять методы Clear() и IsEmpty() с подходящими сигнатурами, но и обеспечивать соответствующее поведение. Liskov substitution — именно об этом.

К сожалению, известные мне мейнстримные языки (и Rust, увы тоже) не позволяют формально специфицировать поведенческую часть контракта, и приходится фиксировать ее в юнит-тестах. Убого и ненадежно, ну да видно для лучших инструментов время еще не пришло. Baby steps.

Исправление Manhunt, :

Функции, которые используют базовый тип, должны иметь возможность использовать подтипы базового типа, не зная об этом.

Опять же наследование отсутствует, и этот принцип не имеет смысла.

Заблуждение. Liskov substitution нужно иметь ввиду всякий раз, как ты реализуешь какой-либо трейт. Дело в том, что контракт, на который полагаются клиенты этого трейта, включает в себя (помимо сигнатур методов) ещё и определенное поведение этих методов. Скажем, если ты у некоего контейнера вызвал метод Clear(), то ты ожидаешь, что последующий вызов метода IsEmpty() вернет True (в однопоточной программе). Реализация контейнера должна не только предоставлять методы Clear() и IsEmpty() с подходящими сигнатурами, но и обеспечивать соответствующее поведение. Liskov substitution — именно об этом.

К сожалению, известные мне мейнстримные языки (и Rust, увы тоже) не позволяют формально специфицировать поведенческую часть контракта, и приходится фиксировать его в юнит-тестах.

Исходная версия Manhunt, :

Функции, которые используют базовый тип, должны иметь возможность использовать подтипы базового типа, не зная об этом.

Опять же наследование отсутствует, и этот принцип не имеет смысла.

Заблуждение. Liskov substitution нужно иметь ввиду всякий раз, как ты реализуешь какой-либо трейт. Дело в том, что контракт, на который полагаются клиенты этого трейта, фиксирует (помимо сигнатур методов) ещё и определенное поведение этих методов. Скажем, если ты у некоего контейнера вызвал метод Clear(), то ты ожидаешь, что последующий вызов метода IsEmpty() вернет True (в однопоточной программе). Реализация контейнера должна не только предоставлять методы Clear() и IsEmpty() с подходящими сигнатурами, но и обеспечивать соответствующее поведение. Liskov substitution — именно об этом.

К сожалению, известные мне мейнстримные языки (и Rust, увы тоже) не позволяют формально специфицировать поведенческую часть контракта, и приходится фиксировать его в юнит-тестах.