THE INSANE JAVA

曾每日與 Java 搏鬥的 .NET Programmer 日誌

C# 3.0 saves my life as GUI developer

leave a comment »

事先聲明,我是"食人口水尾“的,不是原作者。

UI thread-safe update 一直是件麻煩的事,Winform 如是,Swing 亦如是。Winform 裡用 Control.InvokeRequired, Control.Invoke;Swing 則有 SwingUtilities.invokeLater。兩者都能叫 developer 快樂到死。.NET developer 比較幸運,因為 C# 的演進間接令 thread-safe UI processing 變得簡單。

C# 1.0 + .NET Framework 1.x

public delegate void UpdateStatusBarDelegate(string status);
public void UpdateStatusBar(string status)
{
    if (InvokeRequired)
    {
        Invoke(new UpdateStatusBarDelegate(UpdateStatusBar), new object[] { status });
        return;
    }

    statusBar.Text = status;
}

真的醜死了。一行簡單的 assignment statement 忽爾變得好擁腫。幾乎每次 update UI 都要給它一個新的 delegate,好想哭出來。

C# 2.0 + .NET Framework 2.0

public void UpdateStatusBar(string status)
{
    if (InvokeRequired)
    {
        Invoke(new MethodInvoker(delegate { UpdateStatusBar(status); }));
        return;
    }
    statusBar.Text = status;
}

到 2.0 年代事情美好了,但只是這麼一點點。MethodInvoker 出現減少了無謂的 delegate,但整體感覺依然嘔心。

C# 3.0 + .NET Framework 3.5

public void UpdateStatusBar(string status)
{
    this.SafeInvoke(() =>
    {
        statusBar.Text = status;
    });
}
public static class ControlExtensions
{
    public delegate void InvokeHandler();
    public static void SafeInvoke(this Control control, InvokeHandler handler)
    {
        if (control.InvokeRequired)
        {
            control.Invoke(handler);
        }
        else
        {
            handler();
        }
    }
}

就是應該這樣嘛!簡潔多了。多虧 Extension Method 和 Lambda Expression ,生命從未試過如此美好。那個 ControlExtensions class 只要寫一次,以後便無痛無癢。帥吧。C# 3.0 真是好東西,會令人寫上癮的。

Written by Sean

11 四月, 2008 at 4:38 下午

FleXtense 。 Flex 。 Web Services

leave a comment »

Picture 2.png

好一個 ActionScript web services proxy generator 。簡單直接。

主要功能

1. Generate strong typed proxy classes for web services. 這真是做福人民呀。Intellisense 重見天日。

2. 上述一點還不足夠嗎?

Flex 實在令人又愛又恨。打從 Flex 1.0 起已經開始把玩,當年也可算是劃時代的產品,簡單的一個 MXML 加少量的 ActionScript 已經足以將當時的 ASP JSP 比下去。時至今日,Flex 3.0 的轉變說多不多,說少不少。Component Library 、Class Library 是強大了,但 ActionScript 仍然很爛。那些模仿 OO 但又學得不像樣的語法及行為 ,對於長期浸淫 Java 與 C# 的我來說實在是太嘔心了。再加上早已被 Eclipse, Visual Studio 的 Intellisense 寵壞了﹐對著 Flex Builder 3 真的要哭出來。最討厭是 ActionScript 的 event subscription mechanism,時而像 .NET 的 delegate method,時而像 Java 的 ActionListener,完全無法捉摸,又沒有 Intellisense 幫助,弄得每次都要到 livedoc 找 API Reference,費時失事。連 Adobe 自己都承認 ActionScript 3.0 以前是一塌胡塗:

“Unfortunately, the syntax used by the various event models overlap in various ways, and differ in others. For example, in ActionScript 2.0, some properties, such as TextField.onChanged, can be used as either a callback function or an event listener. However, the syntax for registering listener objects differs depending on whether you are using one of the six classes that support listeners or the UIEventDispatcher class. For the Key, Mouse, MovieClipLoader, Selection, Stage, and TextField classes, you use the addListener() method, but for components event handling, you use a method called addEventListener()."

喜歡 proxy class 原因不單是為 Intellisense ,最重要是 type safe,省了 casting 的功夫。Code 看起來更簡潔實在。

簡易三寶,wsdl url、package name、output directory。完成。

Picture 3.png

ASP.NET Web Services 裡的 business entity

Picture 6.png

asmx 裡邊的一個簡單 method

Picture 9.png

換成 ActionScript 後大概的模樣

Picture 4.png
Picture 8.png

應用時變得更直覺,語法更自然易懂

Picture 5.png

從此不用再見到那些可怕的 e.Result[“Symbol"] 之類的 typeless 語法。可喜可賀。

FleXtense 缺點還是有的

1. Proxy classes 只可 output 到一個指定的 directory,不支援 package。Business entities, services 全都放到同一個地方去。

2. 只有 Windows 版本,沒有 Mac 版本。

Written by Sean

11 四月, 2008 at 12:24 上午

勇闖玻利維亞

leave a comment »

勇闖的人當然不是我,還沒有能耐到玻利維亞。

昨晚早了回家,一邊吃 EDO 的巨浪大切,一邊看 Ian 主持的 Globe Trekker。印象中已經看過這一輯幾遍了,但都是零零碎碎的,連介紹什麼地方都不知道,今敞是頭一回看畢全集。玻利維亞( Bolivia )在南美洲 ,聽了也不知道是啥地方。認識的南美洲國家不外乎是巴西智利阿根廷秘魯烏拉圭,都是沿海國家,玻利維亞就是少數的內陸國家。這個國家並不風光,是南美中最窮的一個。乾旱,資源缺乏,生活水平低,連 Ian 都說是一個頗難旅遊的地方,可想而知普通人應該去不了那裡。

南美洲最吸引人的是它複雜的地理環境。在委內瑞拉裡有世界其中一個最高的瀑布 Angle Fall,光是流水量已叫人目瞪,確實是一個叫人神往的地方,有幸的話此生必到。玻利維亞有世界最大的鹽湖,其浩大的程度足以在 Google Maps 裡看到。不用 zoom in 到四分一已經可以看到白色的湖。不過令我驚訝的不是鹽湖本身,反而是在其邊緣的一個"大城市" Uyuni 。在電視裡看到的,是何其荒涼的一個地市,四處塵土飛揚飛揚,殘破的房屋,一點生命的氣息都沒有。實在無法想像到底人是如何(為何)活在這樣的一個地方。我不是要大驚小怪,佯作驚訝,世上不難發現比玻利維亞更窮的國家,但玻利維亞更帶了一點點蒼涼。

Uyuni 鹽湖旁的一個城市
http://maps.google.com/?ie=UTF8&ll=-20.460711,-66.822581&spn=0.012967,0.020599&t=h&z=16

Uyuni.jpg

鹽湖中心的一所酒店 Palacio del Sal,很有趣,都是用鹽建成的
http://maps.google.com/?ie=UTF8&ll=-20.330724,-67.04683&spn=0.003244,0.00515&t=h&z=18

Salt Palace.jpg

Colchani 鹽湖旁另一個小鎮,真是個鳥不生蛋的地方。人是何其耐苦的動物,這樣一個地方也可居住。
http://maps.google.com/?ie=UTF8&t=h&ll=-20.300686,-66.936865&spn=0.003245,0.00515&z=18

Colchani.jpg

每次看 Globe Trekker 主持走遍落後或發展中國家,都會很陳腔濫調地感嘆世界真大。 地球的一方人們正在艱苦地生活著,另一方則悠閒地舒適地邊吃薯片邊看著別人如何艱苦地生活著。從來不相信世界有公平。

在玩 Google Maps 時,心血來潮輸入了 Easter Island,才發現這個太平洋小島原來是有原居民兼有能夠停泊 747 的機場……一直以為是個了無人煙的小島,地理常識真有夠遜。忽然很想到此地一遊,到 Google 那邊找找,發現有幾位台灣人曾到那裡露營!在太平洋中心露營,真是爽死了。XD
131887_1007_m.jpg

看過關於復活節島的歷史,發現這個小島很早以前已經被人類文明污染了,那些 Moai 的來源一點也不神秘。知道多了,興致反減了。

Written by Sean

8 四月, 2008 at 11:30 下午

張貼於Travel

Some Thoughts on Model View Presenter

leave a comment »

I’ve been using Passive View favor of Model View Presenter (MVP) pattern for a while and satisfy with the flexibility and testability it gives me. Until recently I smelled a rat when started building a fairly complex winform. Something missing, not addressed by others before with this pattern. The view interface looks like this:

public interface IProductView
{
        string ProductName { get; set; }
        Color ProductNameBackColor { get; set; }
        bool ProductNameVisible { get; set; }
        ......
}

It’s clear that data-centric properties (ProductName) and appearance-centric properties (ProductNameBackColor, ProductNameVisbile) are all mingled in the same interface. It’s okay if the view is relatively simple, when comes to a complex one, it can turn terribly ugly. After googling for a while, I found that most tutorials and articles I came across on MVP shared the same characteristic, the view interface is completely data-centric, like the one below:

public interface IProductView
{
        string ProductId { get; set; }
        string ProductName { get; set; }
        double Price { get; set; }
        bool IsOnSale { get; set; }
}

Most people just neglected the appearance-centric properties. Although a view abstracts a form, to me, it still represents a “visual element", which has colors and visibility. How is the presenter supposed to access and change non-data centric UI properties? This is really a dilemma to me. In order to let the presenter controls view logics, UI properties have to be exposed via view interface somehow. One approach is to abstract all controls like this:

public interface IProductView
{
        ITextEdit ProductId { get; set; }
        ITextEdit ProductName { get; set; }
        INumericEdit Price { get; set; }
        IBooleanEdit IsOnSale { get; set; }
}

public interface ITextEdit
{
        string Text { get; set; }
        Color BackColor { get; set; }
        Color ForeColor { get; set; }
        bool Enabled { get; set; }
        bool Visible { get; set; }
}
......

In this case I can stub all controls and put expectation on them in unit test, also the view interface looks much cleaner. I struggled (and still struggling at the time I am writing this) not to do this, for one thing it creates unnecessary complexity (forces me to create custom wrapper classes for common windowsforms controls and implement the custom interface), for the other reason, initializing test cases becomes clumsy as all ITextEdit, INumericEdit require a stub. For instance, to test whether a particular view property has been set or not, currently I can do something like

Expect.Call(view.ProductName = "Product ABC");

But with this extra layer of abstraction, I have to write 2 more lines of code

ITextEdit productNameEdit = mocks.Stub<ITextEdit>();
Expect.Call(view.ProductName).Return(productNameEdit);
Expect.Call(productNameEdit = "Product ABC");

I dug through all the MVP materials again trying to find some insight, one suggested that a twisted MVP will do, but the introduction of an extra controller is somewhat confusing and hard to scope. I am yet to figure out the best approach to address this problem. 😦

References

Martin Fowler’s GUI Architecture Essay (authoritative speak of GUI patterns and many others, although he refused to admit)
Rich Newman’s MVP, MVC comparison (plus introduction to Smart Client Software Factory)
Derek Greer’s MVP, MVC and PAC comparison

Written by Sean

24 三月, 2008 at 12:38 上午

Nikon D60 小試後感

leave a comment »

作為第一部 DSLR ,我很滿意 D60 的表現。

在 01 爬文爬多了,人會變得好迷失,怕買了不適合自己的型號級別。相同價位的 Canon 450D 、Sony a350 看似功能更好,過千萬像數,又有 Live View。思前想後,又開始問自己要買是不是應該買更好更貴的 Nikon D80 、Canon 40D。弄得人有點精神恍惚,懷疑自己是否已經患上 01 綜合症候群。結果在友人的一句「買了才有得玩嘛!」說話底下,再加上假期前消費意欲指數急速上升,不加思索地就敗了 D60。對!反正我就是要消費,買了才好說。

回家開箱後(本想來個開箱文,還是算了,沒這耐性)先試一下那 ISO 1600 的效果。很不錯嘛,那麼黑的環境還看得出一個模樣,換了是我以住那部 DC ,哈哈哈。
DSC_0022.JPG

晚上,全黑無燈(只有附近大廈的光),手持加 1600 ISO 。都變成白天了!那防震鏡頭還真行。
DSC_0028.JPG

白天照,成色準,就是喜歡色彩較濃,以後不用後製了。:)
DSC_0053.JPG

太清楚了……砂子、毛髮、穢物通通看得見……是時候要洗澡了。
DSC_0063.JPG

色彩是不錯了,不過魚兒游太快,試了多個快門組合,總是捉不到影。
DSC_0079.JPG

玩了半天,感覺良好。反應快,儲相也快。亦沒有像 D80 般的 button clutter。很多人說入門級 DSLR 太小巧,沒地方放尾指,不好握,我倒沒這問題,尾指沒那麼粗。重量嘛,可以輕多一點更好,始終去旅行時整天拿著也很吃力。

剛買回來時母親大人嚷著要試玩,拿上手便問:
「為何螢幕沒畫面?怎麼影好?」
「從那個窗看出去喇,你從前沒用過菲林相機嗎?」
「沒可能,現在的相機全都用螢幕,怎麼你會買個這樣落伍的?」
「……」
「可以攝錄影片嗎?」
「不可以喇……」
「不好玩的,這台機真爛」
「……」 orz

後記

1. Active D-Lighting 不好用,有點像軟件後製,並非光學補償。感覺上用了 Active D-Lighting 破壞了相片原有的自然光線及色彩。另外開啟後儲相也慢了,特別是晚上要一至兩秒才能完成儲存。

2. 雖然 Kit 鏡有防震,用上 1600 ISO 在室內影仍然有手震情況。可能是我對 DSLR期望太高,滿以為大光圈(相比一般 DC)加 1600 ISO 應該可以解決一直以來室內攝影不夠光的情況。f3.5 仍然是不足夠呀,很想再敗一隻 f2.8 恆定光圈鏡試試……orz。想想也夠敗家。

3. 螢幕色彩自然,在機上螢幕看與在電腦螢幕上看沒大分別。這點很難得,以住用過的 DC ,無論是 Canon, Panasonic, Sony 都出現過光或過暗的情況,每次將相片放入電腦後看都有貨不對版、被騙了的感覺。

4. Nikon 的成色很合我口味。不買 Canon 原因是相片色彩太自然、太真實,我眼睛吃慣了重鹹,喜歡色彩鮮艷濃烈對比強的相片。不買 Sony 是因為成色太假了,特別是紅和藍,感覺就像是用了原始碼的 #ff0000 紅和 #0000ff 藍,細節都沒有了,很可怕。

5. 沒 Live View 這個問題嘛。買之前是有擔心過,買之後發現擔心是多餘的。還沒有遇到非用 Live View 不可的情況。

6. 真正問題來了。購入 DSLR 後就一直在想,是否要買一套比較專業的軟件去配合呢?例如 Aperture 2。是否要買多幾隻鏡頭在不同場合用呢?Tamron A16N II CP值很高,很想敗。又,好不好買一個新的相片打印機一起玩玩呢?Canon Selphy ES2 看似不錯喔。還有這個那個……=.=" 我認,我是典型消費主意者,完全地嚴重地缺乏自我控制能力。

Written by Sean

22 三月, 2008 at 3:04 上午

張貼於Toys

復活節新玩具

leave a comment »

作為台灣之旅的準備。當然這只是藉口。

可惡的01,那一篇又一篇的開箱文…..害我今年敗了又敗。

nikond60s.jpg

Written by Sean

21 三月, 2008 at 7:42 下午

張貼於Toys

For those java freaks

leave a comment »

welcome 🙂

Written by Sean

10 九月, 2007 at 11:07 下午

張貼於java.lang.*;, System;