accessors 小註解

accessors 指的是物件導向語言裡面的 accessor methods. 根據 [1], 它是用來返回或設定 private field 的值. 取值的時候用 get 開頭的  method (getter), 像是 public String getLotteryNumber(). 設值的時候用 set 開頭的 method (setter), 像是 public String setMyBankAccount(), 此時稱之為 mutators. 但的確也有人把 get 和 set 都混稱為 accessors [2], 所以我也就以一當二, 省掉一些文字.

顯然地, accessors 是用 public 的方法去影響 private field. 正常來說, 在使用者無感的情況下, 它可以做到 [1]:

  • change how the data is handled behind the scenes, 像是改變 method 的定義.
  • impose validation on the values that the fields are being set to, 像是修改 data 的值域.

當然, 這就造成了反對者的批判.  [Ref 2] 的作者 Allen Holub 認為, 如果需要修改 type 等等, 只需要在特定的地方操作, 不需要有個 method 把幾百幾千個 call accessors 的地方都暴露在危險之中. 故 accessors 違背了物件導向封裝的原則.

What if you need to change the accessed field's type? You also have to change the accessor's return type. You use this return value in numerous places, so you must also change all of that code. I want to limit the effects of a change to a single class definition. I don't want them to ripple out into the entire program.

Since accessors violate the encapsulation principle,…

比較不那麼義正辭嚴, 相對搞笑的批評是這個 [3], 他有十大理由使用 setter 和 getter, 但是怎麼看都有點明褒暗貶.

  1. When you realize you need to do more than just set and get the value, you don't have to change every file in the codebase.
  2. You can perform validation here.
  3. You can change the value being set.
  4. You can hide the internal representation. getAddress() could actually be getting several fields for you.
  5. You've insulated your public interface from changes under the sheets.
  6. Some libraries expect this. Reflection, serialization, mock objects.
  7. Inheriting this class, you can override default functionality.
  8. You can have different access levels for getter and setter.
  9. Lazy loading.
  10. People can easily tell you didn't use Python.

​不管正反意見如何, 總之 C#, Action Script, Javascript 都可以用 accessors. 當我們以 Javascript 寫在 HTML 裡面時, 比較沒有被陌生人引用的風險, 相對地好處較為明顯. 但 Javascript 1.8.1 開始, 硬是限制了 setter 的用法 [Ref 5,6], 而 getter 只是取值而已故不受影響.這大概是 2008 年的事.因為我正在讀的 "新書" 裡面有提到 setter/getter, 所以幫它考證一下.

{{ js_minversion_note("1.8.1", "自 JavaScript 1.8.1 起,在設定物件和陣列裡的初始化子的屬性時,不再可以呼叫 Setter。") }}

Starting in JavaScript 1.8.1, setters are no longer called when setting properties in object and array initializers.

[ref]

1. Accessors and Mutators

2. Why getter and setter methods are evil

3. Why use getters and setters?

4. Javascript Getters and Setters for localStorage

5. Getter 和 Setter 的定義

6. set

電瓶燈亮了

前陣子, 我在開高速公路的時候突然發現電瓶燈亮了起來! 哇! 難道是我開 GPS、充手機、又用行車紀錄器的關係嗎? 我趕快把充電器們都拔掉, "果然", 開了幾分鐘紅燈就滅了.

不過事情並沒有這麼單純, 後來在沒有用充電器的情況下, 紅燈又亮了幾次.同樣地, 關掉冷氣、收音機什麼的, 節能減碳開一陣子, 紅燈就會滅了. 顯然這已經看到 bug了, 但真正的原因是什麼呢?

短途車開太多, 電瓶的電不夠用嗎? 雖然確實有這種說法, 不過我的生活型態一直都是如此, 以前卻不會發生啊! 再說, 總不能因為住得離公司太近而離職或搬家吧!

電瓶壞了嗎? 有可能, 但是電瓶壞了的症狀, 應該一停車就經常發不動, 或者再也發不動才對. 在發動的方面, 我倒是沒問題. 所以應該不是這個原因.

換個電瓶大概 3,000 多塊吧! 果真如此, 災情還不算是最嚴重的等級.

那麼這個紅燈的意思是什麼? 為何可以亮了又暗呢? 原來這個燈不是表示沒電, 而是表示沒在充電. 可能的原因有 3 個:

1. 發電機皮帶鬆了.時而發電, 時而不發電.(調整或更換, 換新 1,000 NTD 左右)

2. 發電機壞了, 不發電或偶而不發電 (碳刷壞了之類的). (6~7,000 NTD 左右)

3. 發電機到電瓶的連接線故障, 發了電但充不進去. (2K NTD 以上)

本人這次經過原廠鑑定奪得頭彩, 所以換個發電機了事.值得提醒大家的是: 發電機只保固一年"或"兩萬公里. 這東西無法保養, 又影響行車安全.請大家要多注意電瓶燈的狀況.

[ref]

1. Metrostar電瓶警示燈偶而亮燈問題

2. 汽車行駛時電瓶燈是亮的是代表哪裡出問題?

 

DD 小整理

普通上班族可能一輩子都沒聽過這個名詞,因為沒聽過會更好. 什麼是 DD 呢? 它是財務盡職調查 (finacial due diligence) 的簡稱. 由於中文和英文同樣繞口, 大家比較常用 DD 來代表這件事的動詞和名詞.

舉例來說, 上司突然跟你說: "明天有人來 DD, 快交一份可能專利技術清單給我!" 這樣無論主管或是部屬的寒毛都會豎起來! 如果是聽到 "有人來盡職了!", 感覺氣勢不佳! "有人來調查了!" 感覺又好像做錯事要東窗事發, 顯然詞不達意.更別說 "盡查來了!" 聽起來很像 "警察來了!" 所以 Manny 就是 Manny, DD 就是 DD.

DD 要做的事情類似會計師在查閱財報, 主要是分析被併購公司的真正價值. 有人會想: 那為什麼不看會計師簽證過的財報呢? 會計師主要的工作是收取公司的報酬,並且為公司自結的財報背書. 只要公司的財報不犯法、不違背會計原則與內控原理, 他們就會領錢收工.

我們常在公司財報中看見: "XXX 公司業已編製 OOO 年之合併財務報表,並經本會計師出具無保留意見之查核報告在案, 備供參考". 的字樣. 這僅僅是表示會計師在一段期間內沒看出什麼毛病. 就算看出什麼問題, 可能也只是很保守地改為 "非無保留意見" 或 "除…外, 無保留意見." 扯破臉的狀況少之又少.

相反地, DD 要知道被併購公司 "正常" 的公允價值是多少? 就不能這麼官樣文章了. 不但要看 "量", 還要看 "質". 所謂的質是首先關心盈餘品質 (Quality of Earnings, QoE).

基本上, 會從下列的項目中去分析盈餘的細節: 營收與毛利 – 包括十大客戶, 營業分析, 業外收入(支出), 關係人交易等等.

最常用的盈餘品質指標是 EBITDA (earning before interest, tax, depreciation and amortization) – 稅前息前及折舊攤銷前淨利. 例如: 賣土地雖然會賺大錢, 但也導致資產減損, 故它屬於 amortization 類而可以被剔除.

假如被併購公司用了很多盜版軟體, 那麼營業費用顯然就不符品質. 這顯然不是 "可維持盈餘" (maintainable earning), 所以應該列為調整項目.

最後,併購公司所認定的盈餘可以能高於經營團隊自認可以達到的數字. 此時可以訂定額外對價條款 (earn-out), 假如真能達到更好的績效, 併購方也額外再拿錢出來!

其次要關心淨資產品質 (Quality of Net Assets). 基本上會考慮的項目是:應收帳款、存貨、固定資產、退休金負債、或有負債. 一般會依據財會準則公報第九號規定來決定是否將或有負債入帳或是揭露. 但是對 DD 而言,買方應該儘量將有問題的資產從價金中扣除, 或於合約中要求賣方於交割前將轉投資公司處理完畢.此外, 賣方若有逃漏稅、罰單未繳清等等狀況, 也應該列入合約之中, 悉數由賣方負責.

發生機率 金額能否估計 會計處理
很有可能 可合理估計 應估列入帳
無法合理估計 應揭露
有可能 Don't Care 應揭露
極少可能 Don't Care 可揭露

第三個要點是淨營運資金 (Net Working Capital).

淨營運資金 = 應收票據 + 應收帳款 + 存貨 – 應付票據 – 應付帳款- 應付費用.

一家正常營運的公司, 其淨營運資金未必是正數.以製造業來說, 客戶可能月結 60 天又開半年的支票, 所以需要大量的營運資金才能持續進貨生產. 而便利商店主要是收現金, 賣出的東西才算應付帳款, 賣不出去還可以退貨, 那麼用負的營運資金都可以存活.

定義幾個名詞如下:

應收帳款收款天數 (Days Sales Outstanding, DSO)

存貨週轉天數 (Days Inventory Outstanding, DIO)

應付帳款付款天數 (Days Payable Outstanding, DPO)

那麼便利商店的現金轉換循環 = DSO 1 天 + DIO 11 天 – DPO 30 天 = -18 天. 換言之, 應該付給客戶的錢, 有 18 天是可以借來用的. 更誇張的例子是保險業, 錢收進來之後, 會有很多年的時間都可以拿來自由運用. 這顯示了淨營運資金並不是以絕對金額來衡量的, 主要應該與同業相比.

最後是淨負債 (Net Debt). 除了真正的負債之外, 公司如果遭遇訴訟, 就有潛藏的負債危機, 這些歸納為債類型項目(debt-like item). 最保險的方式就是買方把現金與負債都排除在合約之外, 此為排除現金及負債交易 (cash-free and debt-free). 因為用現金買現金是沒有意義的, 所以排除現金的併購也很合理. 萬一那些約當現金的項目, 如政府公債等等賣不到好價錢, 還不如不要將它計算在內.

至於潛藏負債的解決之道還有一個方法, 就是先將買方一部份的價金放在保管帳戶 (escrow account),如果若干時間後發生了訴訟費用, 就直接從保管帳戶扣除.

[REF]

1. 企業併購策略與最佳實務

 

Miracast in Android 小整理

大家都知道 Android 4.2 版支持了以前叫做 WIFI Display 的 Miracast. 看了同事轉寄的網路文章 [1], 才知道 Android 連架構都配合 Miracast 做了修改.

首先考量的是, 使用者需要把手機上的畫面輸出到電視上分享給大家, 卻不能讓大家都看見他/她怎麼在鍵盤上按密碼. 所以 surfaceflinger 就不能把虛擬鍵盤或是密碼框的這一層投射出去. 換言之, 把整個 display planes  (什麼 V1, V2, OSD1, OSD2, SUB1, SUB2) 都 mix 後才輸出的那張圖, 反而不是可以公開的.

因此, surfaceflinger 裡面就多了個 display device 的抽象層.

DISPLAY_PRIMARY:  Android 手機的螢幕

DISPLAY_RXTERNAL: HDMI 設備, 如 TV

DISPLAY_VIRTUAL: WIFI Display, 即 Miracast.

1357478805_4074

對於 virtual 的裝置, Android 並不準備它的 frame buffer.從下面這段 code 中可以看出, 每一個 Display Device 在產生的時候, 都會參考 state.isVirtualDisplay 是否為真? 進而決定 hw 這個 class 的內容. Miracast 顯然就和 HDMI, 和 local 螢幕不同類. 可見得在 HDMI 以 MHL (Mobile High-Definition Link) 接電視的情況下是允許看到輸入密碼視窗的, 但 Miracast 以 WIFI 無線時不可以顯示.

1357478788_3356

其中 static_cast< sp<ISurfaceTexture>> 表示指定型別為 sp<ISurfaceTexture>, 也就是 ISurfaceTexture 的 smart pointer. Smart pointer 也是個 pointer, 它有助於在不同的地方 create 和 destroy, 因此可以靈活地運用並減少記憶體丟失 (或曰"洩漏").它的原文是:

Smart pointers ensure we properly destroy an object even if its creation and destruction are widely separated. They make functions simpler and safer by ensuring that no matter how many different exit paths exist, local objects are always cleaned up correctly. They help enforce that exactly one object owns another object at any given time, preventing both leaks and double-frees.[2]

最後 Android 做 composer 的時候, 會對每一種顯示設備 (共 mDisplays.size 種) 檢查是否 dirty (需要更新)? 並且用 hw->canDraw() 判斷能不能畫? 如果不能畫, 連 dirty 也不畫.在 2011 年的時候, 就有人抱怨過 hw->flip 為什麼在 hw->canDraw() 的前面執行 [3]? 導致 Android suspend 的時候都還在 flip. 看來 Android 是從善如流, 改為優先判斷 canDraw() 了.

1357478824_6904

[REF]

1.Android Wi-Fi Display 介紹

2.Smart Pointer Guidelines

3.Android的Suspend​

HDMI CEC 的一點補充

自從遇見 HDMI (High Definition Multimedia Interface) 的 CEC (Consumer Electronics Control ) 之後, 就被這個又方便又容易出問題的功能發了很多 bug.

有時候它可以用 device (例如 DVD Player, BD Player, Digital Media Player…等等, 簡稱 box 好了) 的搖控器控制電視, 有時候又反過來是用電視的搖控器控制 box. 雖然它們的目的都是減少使用者拿兩支以上搖控器的不便, 但實作起來卻有很大的差異.

有個規格 (protocol) 叫作 RC pass through. RC (remote pass through) 就是搖控器, pass through 就是控制到另外一台裝置. 例如用電視遙控器去播 box. 規格上並沒有說不能用盒子的遙控器去控制電視, 所以兩個方向都有可能. This feature is used to pass remote control commands received by one device (typically the TV) through to another device in the network.

首先我們把 TV 切到 box 所在的 HDMI port, 然後拿電視的遙控器來控制 box 就可以了. 前提是兩台裝置都支援 RC pass through. 當然, 規格不能保證所有的搖控器鍵值都可以傳給別台裝置. 合法的功能寫在 HDMI 1.4 規格的 table 30.

CEC-1.4-Table-30-620x200

其實 HDMI 1.3 講得比較簡單易懂. HDMI 1.4 裡面引進了 <feature abort> 的觀念, 遇到某些不支援的 protocol 或是 command 時, 產生的結果也會不一樣.  因此 HDMI 1.4 還要參考的表格是 table 20, 27 和 27 三張.  HDMI 1.3 裡面只有一個 table 23 則對應到 HDMI 1.4 的 table 30 而已. HDMI 1.4 又定義了久按TV 遙控器按件不放時, 則每隔 450ms (建議值, 可以定在 200~500 ms) 要重送一次鍵值到 box (反向亦然).

雖然 table 30 裡面功能鍵眾多, 其中只有一部分 (0x60~0x6D) 是 deterministic (決定性的) UI function. 這些按鍵的功能不受到其它條件的影響, 按了就要有正確的反應, 例如 power on, power off 時, 毋須考慮什麼事情正做到一半.

另外一個類似的 protocol 是 device menual control. 同樣地, 看了 HDMI 1.3 的規格就會覺得自己很快懂了. 但是看了 HDMI 1.4 就會覺得好複雜. 它的主要功能就是讓 TV 把 box 的控制面板 (control menu) 叫出來, 這樣就可以真正地操作 box. 否則若是 box 上有什麼特異功能, 光靠 TV 的遙控器也無法做到!

舉個誇張一點的例子, 如果搖控器按"上上下下左左右右","next","previous" 可以叫出某個破解功能, 只用 RC pass through 就很難保證哪些 key 按了 400 ms, 哪些是 600 ms. 在 device menu control 假設可以看到畫面上每個鍵被按到後的反白, 應該就能確定自己按對了. 假如 box 支援虛擬小鍵盤, 也是只有 device menu control 可以輕易使用此功能.

另外, 按照規格上的說法, 它只能單向地由 TV 叫出 box 的 control menu.

HDMI-2-CEC-Case