Статическая / сильная печатание и рефакторинг -- refactoring поле с участием strong-typing поле с участием static-typing поле с участием weak-typing пол Связанный проблема

Static/strong typing and refactoring


6
vote

проблема

русский

Мне кажется, что самая бесценная вещь о статическом / сильно наведенном языке программирования состоит в том, что он помогает рефакторингу: если / когда вы меняете какие-либо API, то компилятор скажет вам, что это изменение сломалось.

Я могу представить себе письменный код в среде выполнения / слабо напечатанный язык ... но я не могу себе представить рефакторинг без справки компилятора, и я не могу представить писать десятки тысяч строк кода без рефакторинга.

.

Это правда?

Английский оригинал

It seems to me that the most invaluable thing about a static/strongly-typed programming language is that it helps refactoring: if/when you change any API, then the compiler will tell you what that change has broken.

I can imagine writing code in a runtime/weakly-typed language ... but I can't imagine refactoring without the compiler's help, and I can't imagine writing tens of thousands of lines of code without refactoring.

Is this true?

</div
           
 
 

Список ответов

13
 
vote
vote
Лучший ответ
 

Я думаю, что вы связываете, когда типы проверяются с тем, как они проверяются. Время выполнения, набрав не обязательно слаб.

Основным преимуществом статических типов является именно то, что вы говорите: они исчерпывающие. Вы можете быть уверены, что все сайты вызовов соответствуют типу, просто позволяя компилятору сделать это.

Основное ограничение статических типов заключается в том, что они ограничены в ограничениях, которые они могут выразить. Это зависит от языка, с большинством языков, имеющих относительно простые системы типа (C, Java) и другие с чрезвычайно мощными типами типа (Haskell, Cayenne).

Из-за этого типов ограничения самостоятельно не хватает. Например, в типах Java более или менее ограничены для проверки имена типов совпадения. Это означает, что значение любого ограничения, которое вы хотите, проверяется, должен быть закодирован в схему именования некоторых соотношений, отсюда и множество нагрузочных элементов и пластин для котельной, распространенной для кода Java. C ++ немного лучше в том, что шаблоны позволяют немного больше выразительности, но не приблизиться к тому, что вы можете сделать с зависимыми типами. Я не уверен, что существует недостаток более мощных типов систем, хотя явно должно быть, некоторые или более люди будут использовать их в промышленности.

Даже если вы используете статический набор, шансы - это не достаточно выразительна, чтобы проверить все, что вы заботитесь о том, поэтому вам нужно будет писать тесты. Будь то статическая набравка экономит вам больше усилий, чем требуется в Boilerplate - это дискуссия, которая проводится в течение возраста, и что я не думаю, что имеет простой ответ для всех ситуаций.

до вашего второго вопроса:

Как мы можем безопасно повторно повторно во время выполнения набранным языком?

Ответ - это тесты. Ваши тесты должны охватывать все случаи, которые имеют значение. Инструменты могут помочь вам в измерении, насколько исчерпывающие ваши тесты. Проверка охвата Инструменты, сообщите, что вы знаете линиевые линии кода, покрыты тестами или нет. Test Mutsation Tools (Jester, Heckle) может сообщить, что ваши тесты логически неполны. Приемные тесты сообщите вам о том, что вы написали соответствующие требования, и, наконец, регрессионные и производительность гарантируют, что каждая новая версия продукта поддерживает качество последнего.

Одним из великих вещей о правильном тестировании на месте, полагаясь на уточнение космений типа, это то, что отлад становится намного проще. При запуске тестов вы получаете определенные неудачные утверждения в тестах, которые четко выражают то, что они делают, а не тупые операторы ошибки компилятора (думайте, что шаблоны шаблонов C ++).

Независимо от того, какие инструменты вы используете: написание кода, вы уверены, что потребуются усилия. Скорее всего, потребует писать много тестов. Если наказание за ошибки очень высоко, например, программное обеспечение в аэрокосмическом или медицинском контроле, вам может потребоваться использовать формальные математические методы для доказательства поведения вашего программного обеспечения, что делает такое развитие чрезвычайно дорогим.

 

I think you're conflating when types are checked with how they're checked. Runtime typing isn't necessarily weak.

The main advantage of static types is exactly what you say: they're exhaustive. You can be confident all call sites conform to the type just by letting the compiler do it's thing.

The main limitation of static types is that they're limited in the constraints they can express. This varies by language, with most languages having relatively simple type systems (c, java), and others with extremely powerful type systems (haskell, cayenne).

Because of this limitation types on their own are not sufficient. For example, in java types are more or less restricted to checking type names match. This means the meaning of any constraint you want checked has to be encoded into a naming scheme of some sort, hence the plethora of indirections and boiler plate common to java code. C++ is a little better in that templates allow a bit more expressiveness, but don't come close to what you can do with dependent types. I'm not sure what the downsides to the more powerful type systems are, though clearly there must be some or more people would be using them in industry.

Even if you're using static typing, chances are it's not expressive enough to check everything you care about, so you'll need to write tests too. Whether static typing saves you more effort than it requires in boilerplate is a debate that's raged for ages and that I don't think has a simple answer for all situations.

As to your second question:

How can we re-factor safely in a runtime typed language?

The answer is tests. Your tests have to cover all the cases that matter. Tools can help you in gauging how exhaustive your tests are. Coverage checking tools let you know wether lines of code are covered by the tests or not. Test mutation tools (jester, heckle) can let you know if your tests are logically incomplete. Acceptance tests let you know what you've written matches requirements, and lastly regression and performance tests ensure that each new version of the product maintains the quality of the last.

One of the great things about having proper testing in place vs relying on elaborate type indirections is that debugging becomes much simpler. When running the tests you get specific failed assertions within tests that clearly express what they're doing, rather than obtuse compiler error statements (think c++ template errors).

No matter what tools you use: writing code you're confident in will require effort. It most likely will require writing a lot of tests. If the penalty for bugs is very high, such as aerospace or medical control software, you may need to use formal mathematical methods to prove the behavior of your software, which makes such development extremely expensive.

</div
 
 
       
       
5
 
vote

Я полностью согласен с твоими чувствами. Сама гибкость того, что динамически напечатанные языки, должны быть хорошими, на самом деле то, что делает код очень трудно поддерживать. Действительно, есть ли такая вещь, как программа, которая продолжает работать, если типы данных изменяются в нетривиальном пути, не изменяя код?

В среднее время вы можете проверить тип переменной пройденной и каким-то образом выйти из строя, если это не ожидаемый тип. Тебе все равно придется запустить свой код, чтобы укоренить те случаи, но, по крайней мере, что-то скажут вам.

Я думаю, что внутренние инструменты Google на самом деле делают компиляцию и, вероятно, введите проверку на их JavaScript. Я хотел бы иметь эти инструменты.

 

I totally agree with your sentiment. The very flexibility that dynamically typed languages are supposed to be good at is actually what makes the code very hard to maintain. Really, is there such a thing as a program that continues to work if the data types are changed in a non trivial way without actually changing the code?

In the mean time, you could check the type of variable being passed, and somehow fail if its not the expected type. You'd still have to run your code to root out those cases, but at least something would tell you.

I think Google's internal tools actually do a compilation and probably type checking to their Javascript. I wish I had those tools.

</div
 
 
   
   
2
 
vote

Чтобы начать, я начечный Perl Programmer так, с одной стороны, я никогда не запрограммировал с сетью статических типов. Ото, я никогда не запрограммировал с ними, поэтому я не могу говорить с их преимуществами. Что я могу говорить, - это то, что это нравится для рефакторы.

Я не нахожу отсутствие статических типов, чтобы быть проблемой рефакторинга. То, что я нахожу проблему - отсутствие рефакторинга браузера . Динамические языков есть проблема, что вы на самом деле не знаете, что код действительно будет делать, пока вы на самом деле не запустить его. Perl имеет это больше, чем большинство. Perl имеет дополнительную проблему иметь очень сложный, почти неперегруппой, синтаксис. Результат: нет инструментов рефакторинга (хотя Они работают очень быстро на том, что ). Конечный результат - я должен рефакторировать вручную. И это то, что представляет ошибки.

У меня есть тесты, чтобы поймать их ... Обычно. Я часто нахожусь перед грязной кучей непроверенного и невыполненного кода, несущественным кодом с проблемой куриного / яиц для рефакторов кода, чтобы проверить его, но чтобы проверить его, чтобы ревертировать его. Ick. На этом этапе я должен написать очень глупые, высокий уровень «Программа выводится на то же самое, что она сделала до« своего рода тестов, чтобы убедиться, что я что-то не сломал ».

Статические типы, как предусматриваемые в Java или C ++ или C #, действительно решайте только небольшой класс проблем программирования. Они гарантируют ваши интерфейсы передаются битами данных с правой этикеткой. Но только потому, что вы получаете коллекция не означает, что коллекция содержит данные, которые вы думаете, что он делает. Потому что вы получаете целое число, не значит, что вы получили правильное целое число. Ваш метод принимает объект пользователя, но входит ли пользователь в системе?

Классический пример: <код> public static double sqrt(double a) - это Подпись для корневой функции Java Square . Квадратный корень не работает на отрицательных числах. Где говорится, что в подписи? Это не так. Еще хуже, где говорится, что эта функция даже делает? Подпись только говорит, какие типы нужны и что он возвращается. Он ничего не говорит о том, что происходит между ними и именно там интересным кодом жизнь. Некоторые люди пытались захватить полный API с помощью дизайн по контракту , который Можно широко описать как встраивание в эксплуатацию тесты в действие вводах ваших функций, выходов и побочных эффектов (или его отсутствие) ... но это другое шоу.

API гораздо больше, чем просто функциональные подписи (если бы не было, вам не понадобится все, что описательная проза в Javadocs) и рефакторинг гораздо больше, чем просто изменение API.

Наибольшее преимущество рефакторинга Статически набратая, статически скомпилированная, нединамический язык дает вам возможность писать инструменты рефакторинга делать довольно сложные рефакторинги для вас, потому что он знает, где все вызовы на ваши методы. Я довольно завистла от Intellij Idrea .

 

To start, I'm a native Perl programmer so on the one hand I've never programmed with the net of static types. OTOH I've never programmed with them so I can't speak to their benefits. What I can speak to is what its like to refactor.

I don't find the lack of static types to be a problem wrt refactoring. What I find a problem is the lack of a refactoring browser. Dynamic languages have the problem that you don't really know what the code is really going to do until you actually run it. Perl has this more than most. Perl has the additional problem of having a very complicated, almost unparsable, syntax. Result: no refactoring tools (though they're working very rapidly on that). The end result is I have to refactor by hand. And that is what introduces bugs.

I have tests to catch them... usually. I do find myself often in front of a steaming pile of untested and nigh untestable code with the chicken/egg problem of having to refactor the code in order to test it, but having to test it in order to refactor it. Ick. At this point I have to write some very dumb, high level "does the program output the same thing it did before" sort of tests just to make sure I didn't break something.

Static types, as envisioned in Java or C++ or C#, really only solve a small class of programming problems. They guarantee your interfaces are passed bits of data with the right label. But just because you get a Collection doesn't mean that Collection contains the data you think it does. Because you get an integer doesn't mean you got the right integer. Your method takes a User object, but is that User logged in?

Classic example: public static double sqrt(double a) is the signature for the Java square root function. Square root doesn't work on negative numbers. Where does it say that in the signature? It doesn't. Even worse, where does it say what that function even does? The signature only says what types it takes and what it returns. It says nothing about what happens in between and that's where the interesting code lives. Some people have tried to capture the full API by using design by contract, which can broadly be described as embedding run-time tests of your function's inputs, outputs and side effects (or lack thereof)... but that's another show.

An API is far more than just function signatures (if it wasn't, you wouldn't need all that descriptive prose in the Javadocs) and refactoring is far more even than just changing the API.

The biggest refactoring advantage a statically typed, statically compiled, non-dynamic language gives you is the ability to write refactoring tools to do quite complex refactorings for you because it knows where all the calls to your methods are. I'm pretty envious of IntelliJ IDEA.

</div
 
 
 
 
1
 
vote

Я бы сказал, рефакторинг выходит за рамки того, что компилятор может проверить, даже на статически набираемых языкам. Рефакторинг просто изменяет внутреннюю структуру программ, не влияя на внешнее поведение. Даже на динамических языках есть еще вещи, которые вы можете ожидать, чтобы произойти и тестировать, вы просто потеряете немного помощи от компилятора.

 

I would say refactoring goes beyond what the compiler can check, even in statically-typed languages. Refactoring is just changing a programs internal structure without affecting the external behavior. Even in dynamic languages, there are still things that you can expect to happen and test for, you just lose a little bit of assistance from the compiler.

</div
 
 
1
 
vote

Одной из преимуществ использования VAR в C # 3.0 заключается в том, что вы CAN часто меняют тип, не нарушая какой-либо код. Тип должен по-прежнему выглядеть то же самое - свойства с одинаковыми именами должны существовать, методы с одинаковой или аналогичной подписью все еще должны существовать. Но вы действительно можете измениться на совершенно другой тип, даже без использования чего-то вроде Resharper.

 

One of the benefits of using var in C# 3.0 is that you can often change the type without breaking any code. The type needs to still look the same - properties with the same names must exist, methods with the same or similar signature must still exist. But you can really change to a very different type, even without using something like ReSharper.

</div
 
 

Связанный проблема

2  Можем ли мы сделать этот фрагмент Grovier?  ( Can we make this snippet groovier ) 
Есть ли улучшения, где я могу улучшить этот код? Может быть, есть некоторые функции Groovy языка? Этот фрагмент снимает XML-файл: Узел / Узел / Узел <код> d...

0  Какой плагин или расширение jQuery можно использовать для создания строки запроса?  ( What jquery plugin or extension could i use to construct a query string ) 
На данный момент мы строим наш поисковый запрос на нашем сайте с помощью Java Script. У нас есть поле ввода для ключевого слова и другое входное поле для имен...

0  Как исправить и реформировать этот сценарий калькулятора в JavaScript / jQuery  ( How to fix and refactor this calculator script in javascript jquery ) 
Я решил попробовать и узнать больше jQuery, а вот что я придумал. Это должно быть достаточно простая работа, но я не могу заставить голову вокруг него. Я мо...

17  Как модулировать (большое) java приложение?  ( How to modularize a large java app ) 
У меня есть довольно большое (несколько MLOC) приложение под рукой, что я хотел бы разделить в более удобные отдельные части. В настоящее время продукт состои...

10  Самый чистый способ найти совпадение в списке  ( Cleanest way to find a match in a list ) 
Какой лучший способ найти что-то в списке? Я знаю, что LINQ есть хорошие трюки, но давайте также получим предложения для C # 2.0. Давайте получим лучшие рефак...

3  Предотвращение дубликата кода на входной проверке  ( Avoiding duplicate code in input validation ) 
Предположим, у вас есть подсистема, которая делает какую-то работу. Это может быть что угодно. Очевидно, что на точке входа в эту подсистему на входе будут оп...

14  Советы по рефакторируете устаревшую схему базы данных [Закрыто]  ( Tips on refactoring an outdated database schema ) 
<в сторону CLASS = "S-NEWACTS S-WELTIVE__info JS-Post-New Imide MB16« Роль = «Статус»> <Путь d = "M15 6.38A6.48 6.48 0 007.78. 04H-.02A6.49 6.49 0 002.05 ...

2  Рефакторинг Netbeans "Reignline"  ( Netbeans inline variable refactoring ) 
Возможно ли встроен (и наоборот) переменные с рефакторингом NetBeans? что-то вроде этого: <код> Something s = new Something(); render(s); должен стать...

124  Кодирование кат для практики рефакторирования наследие  ( Coding katas for practicing the refactoring of legacy code ) 
Я вполне заинтересован в кодировке Катас в последние месяцы. Я считаю, что они отличный способ отточить свои навыки программирования и улучшить качество кода,...

1  Класс тестирования с несколькими методом объекта  ( Test class with several method object ) 
У меня есть класс какая-то сложная логика, поэтому я решаю использовать использование объект метода < / a> несколько раз, чтобы рефакторировать его. Предпо...

1  Я использую форму рельсов правильно?  ( Am i using the rails form properly ) 
Я чувствую, что понятия не имею, что я делаю .. У меня есть расплывчатая идея. Я надеюсь, что сделал это все в порядке. Любой способ, которым вы можете посм...

4  Git: Massive Refastor сохраняет изменения журнала  ( Git massive refactor keeping changes log ) 
Можно ли сделать массивный ревертор, который включает в себя движущиеся и переименовать многие каталоги, не теряя отслеживание изменения Git? ...

1  Как рефакторировать процедурный RPC PHP к ориентированному объекту?  ( How do i refactor procedural rpc php to object oriented ) 
У меня есть наследие API в PHP, что мне нужно рефактору. Запрос должен включать операцию (например, «get_some_data»), которая определяется в массивной последо...

0  Как Refactor ASP.NET MVC ActionResult?  ( How to refactor asp net mvc actionresult ) 
Как я получаю дальше в создание моего веб-сайта ASP.NET MVC, я сталкиваюсь с некоторыми жесткими кодировкой, который я хочу рефакторировать во что-то немного ...

3  Разрешение переменной с родительскими нулевыми значениями  ( Variable resolution with parent null values ) 
У меня есть метод, который имеет много многочисленков, как это: <код> employee.LastName = file.EMPLOYEE.NAME.SUBNAME.FAMILYNAME.NAMEPART1.Value; (это с...

Связанный проблема

2  Можем ли мы сделать этот фрагмент Grovier? 
0  Какой плагин или расширение jQuery можно использовать для создания строки запроса? 
0  Как исправить и реформировать этот сценарий калькулятора в JavaScript / jQuery 
17  Как модулировать (большое) java приложение? 
10  Самый чистый способ найти совпадение в списке 
3  Предотвращение дубликата кода на входной проверке 
14  Советы по рефакторируете устаревшую схему базы данных [Закрыто] 
2  Рефакторинг Netbeans "Reignline" 
124  Кодирование кат для практики рефакторирования наследие 
1  Класс тестирования с несколькими методом объекта 
1  Я использую форму рельсов правильно? 
4  Git: Massive Refastor сохраняет изменения журнала 
1  Как рефакторировать процедурный RPC PHP к ориентированному объекту? 
0  Как Refactor ASP.NET MVC ActionResult? 
3  Разрешение переменной с родительскими нулевыми значениями 



© 2021 www.qaru.top All Rights Reserved. Q&A House все права защищены


Licensed under cc by-sa 3.0 with attribution required.