воскресенье, 18 апреля 2010 г.

Java - отличная платформа, но слишком неповоротливый язык.

Хотел поделится порцией очевидностей. Java - это действительно отличная платформа для разработки, с больших комьюнити, огромным числом Open Source библиотек, инструментов и т.п. Но вот язык Java этой платформы слишком устарел. Лично я не поклонник нагромождения синтаксического сахара, как например в Ruby. Но я сравниваю с C# и там есть много действительно полезных плюшек, практически полезных (я вообще пишу только о том, с чем лично столкнулся).
Вот два небольших примера.
1. Есть очень популярная задача, организовать конвейер для обработки документов, которые по сути из себя представляют Map или, если говорим о C#, Dictionary. К Dictionary в дот нете, у меня есть одна большая претензия, он слишком часто кидает исключения. Но речь не об этом. Вот так выглядит простой документ, я добавил в него метод AddProperty, с помощью которого можно не только добавить элемент, но и перезаписать старый:
  1. public class Document : Dictionary<stringobject>  
  2.     {  
  3.         public Document AddProperty(string name, object value)  
  4.         {  
  5.             if (ContainsKey(name))  
  6.                 Remove(name);  
  7.   
  8.             Add(name, value);  
  9.             return this;  
  10.         }  
  11.     }  
Собственно ничего интересно, за исключение полезной штучки, метод возвращает не void, а самого себя.
API конвейера тоже простое:
  1. public class Pipeline  
  2. {  
  3.     public void AddProccessor(Func<Document, Document> proccessor)  
  4.     {  
  5.     }  
  6.   
  7.     public void Execute()  
  8.     {  
  9.     }  
  10. }  
Вот тут почти самый главный момент. Делегаты это хорошо, мне надоели в том же свинге листенеры с одним методом, это ужас какой-то.
Но самое интересное теперь. Иногда требуется добавить очень простую обработку, которая просто добавляет пару полей к документу. В java пришлось бы поступить как в свинге, анонимный класс с реализацией метода интерфейса листенера. Но в C# коллега подсказал очень и очень красивое решение:
  1. var pipeline = new Pipeline();  
  2. pipeline.AddProccessor(record => record.AddProperty("NewProp""Value").AddProperty("AnotherProp", 1));  
Действительно в одну строчку.
2. На эту тему копий сломано не мало, перегрузка методов или параметры по умолчанию. Кто бы, что ни говорил, но C# 4.0 c параметрами по умолчанию плюс именование параметров, лично для меня, отличное, красивое и удобно решение.
Вот есть метод:
  1. public static string format(string value,   
  2.             bool option1 = falsebool option2 = false)  
  3. {  
  4.     return value;  
  5. }  
Параметры по умолчанию позволяют не забивать и так не маленькие исходные тексты кучей не нужного текста. Но к сожалению они не идеальны без одной маленькой штучки. Вот скажите, что надо сделать, чтобы вызвать описанный метод, но чтобы option2 был true. Придется или перегружать метод, или при вызове передавать false для option1. Но проблема решена в C# 4.0. При вызове метода передаваемые параметры можно именовать, так что теперь можно не беспокоиться об очерёдности параметров, а также решить указанную выше проблему простым способом:
  1. format("test", option2: true);  
Да, для JVM есть много интересных альтернативных языков, например мне нравится Clojure. Но например у него есть проблемы с производительности и вообще, его активно портируют на CLR. Хотелось бы, чтобы и основной язык платформы более активно развивался.

Ну и так, ещё одна рабочая мысль за сегодня: парное программирование - это не только весело, но и действительно продуктивно.

И совсем напоследок цитата дня (которую правда уже постил в Buzz'е, но уж больно понравилась):
  1. select fun, profit from real_world where relational=false  

понедельник, 5 апреля 2010 г.

Java Decompiler

Да, по названию поста будет понятно о чём речь :)
По старой традиции использовал для этих целей всегда JAD. Но он уже достаточно давно заброшен и не справляется с некоторыми фишками. Нашёл хорошую альтернативу, так прям и называется Java Decompiler. Работает как отдельное приложение, так и как плагин к эклипсу.
Больше всего не давали жить две штуки (исходники, которые мне нужны, были просто напичканы ими): ассерты и дженерики. Вот на составил небольшой демонстрационный примерчик:
Исходный текст:

  1. public class Example {  
  2.       
  3.     public class Doing<T extends Some> extends Base<T> {  
  4.         @Override  
  5.         public T doSomething(T param) {  
  6.             assert(param == null);  
  7.             return param;  
  8.         }  
  9.     }  
  10.   
  11.     public abstract class Base<T extends Some> {  
  12.         public abstract T doSomething(T param);  
  13.     }  
  14.   
  15.     public class Some {  
  16.         public Some doing() {  
  17.             return this;  
  18.         }  
  19.     }  
  20.       
  21. }  
То что выдал JAD:
  1. // Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.  
  2. // Jad home page: http://www.kpdus.com/jad.html  
  3. // Decompiler options: packimports(3)   
  4. // Source File Name:   Example.java  
  5.   
  6. public class Example {  
  7.     public abstract class Base {  
  8.   
  9.         public abstract Some doSomething(Some some);  
  10.   
  11.         final Example this$0;  
  12.   
  13.         public Base() {  
  14.             this$0 = Example.this;  
  15.             super();  
  16.         }  
  17.     }  
  18.   
  19.     public class Doing extends Base {  
  20.   
  21.         public Some doSomething(Some param) {  
  22.             if (!$assertionsDisabled && param != null)  
  23.                 throw new AssertionError();  
  24.             else  
  25.                 return param;  
  26.         }  
  27.   
  28.         final Example this$0;  
  29.         static final boolean $assertionsDisabled = !Example  
  30.                 .desiredAssertionStatus();  
  31.   
  32.         public Doing() {  
  33.             this$0 = Example.this;  
  34.             super();  
  35.         }  
  36.     }  
  37.   
  38.     public class Some {  
  39.   
  40.         public Some doing() {  
  41.             return this;  
  42.         }  
  43.   
  44.         final Example this$0;  
  45.   
  46.         public Some() {  
  47.             this$0 = Example.this;  
  48.             super();  
  49.         }  
  50.     }  
  51.   
  52.     public Example() {  
  53.     }  
  54. }  
И наш чемпион Java Decompiler:
  1. public class Example {  
  2.     public abstract class Base<T extends Example.Some> {  
  3.         public Base() {  
  4.         }  
  5.   
  6.         public abstract T doSomething(T paramT);  
  7.     }  
  8.   
  9.     public class Doing<T extends Example.Some> extends Example.Base<T> {  
  10.         public Doing() {  
  11.             super(Example.this);  
  12.         }  
  13.   
  14.         public T doSomething(T param) {  
  15.             assert (param == null);  
  16.             return param;  
  17.         }  
  18.     }  
  19.   
  20.     public class Some {  
  21.         public Some() {  
  22.         }  
  23.   
  24.         public Some doing() {  
  25.             return this;  
  26.         }  
  27.     }  
  28. }  
Разница заметна на лицо, комментарии излишни :)

Подсветка кода

Ранее я писал как можно сделать подсветку исходного кода в записях с помощью SyntaxHighlighter. Но пару дней назад официальный сайт отвалился и код перестал подсвечиватся. По сути, если подумать, то делать это в динамике, как это делает SyntaxHighlighter нет смысла. Но на серверную сторону блогера повлиять трудно. Поэтому нашёл замечательный сайт. Идея просто, вставляет код, там используется SyntaxHighlighter от которого получаем статический html, и спокойно вставляем её в запись.

Единственный недостаток, с <, > вообщем запрещёнными символами, которые, например, встречаются в LINQ выражениях. Придётся самостоятельно делать эксейпинг.

Да, и ещё одним преимуществом такого статического подхода, является корректное отображения кода в RSS ридерах и пр. трансляторах, js они не могу проинтерпретировать, а со статичным html'ем справляются на ура.

UPDATE: Не знаю как просмотрел, но есть отличная js библиотечка для динамической подсветки highlight.js от Ивана Сагалаева. Поддерживает целых 35 языков и всё время пополняется, кроме того, у неё есть отличный набор из более чем десятка тем. Я себе под новый дизайн выбрал Dark.

<?xml version="1.0"?>
<response value="ok" xml:lang="en">
  <text>Ok</text>
  <comment html_allowed="true"/>
  <ns1:description><![CDATA[
  CDATA is <not> magical.
  ]]></ns1:description>
  <a></a> <a/>
</response>