《修改軟件的藝術》
進行一個預期九個月的專案,到第八個月時,我們發現進度比預期晚了六個月。問題在哪?怎麼會變成這樣的呢?
其實我們一直是晚了六個月,只不過我們到第八個月才發現罷了。
—
敏捷迭代的重點,讓你不斷再次確認目標是否產生變化,是否要調整方向步伐,我們是否能如預期般達成目標。
如果不行,在目前的情況下,我們能做什麼是最有價值的行動呢?
在這過程中,避免因為工作任務顆粒度過大,導致資源無法釋放,無法因應變化去選擇有更價值的工作進行,因此承擔機會成本。抑或是得把已經投入資源進行開發,卻仍無法產生價值的半成品放一旁,因此承擔了沈沒成本。
越早發現問題,修復問題的成本與風險越低。頻繁確認目標以及實際的落差、頻繁交付價值、調整行動,這才能應對現代軟體產品的變化性。
我喜歡這本書,也推薦給想要體會在遺留代碼系統中的敏捷實踐為何的朋友。九個實踐如下:
1) 在問如何做之前,先問為什麼做、給誰做、做什麼。(user story template)
2) 小批次建置,每一段之間都是自動化的鐵路,異動量少,建置發生問題時,根本原因越容易找出來,能得到更快的 feedback ,就能更快的做出反應。
3) 持續整合(Continuous Integration), 持續整合說真的跟 build solution 用哪一套的關係不大,重點在團隊能在多快的時間內讓大家寫的程式變成一份並確認執行無誤。
持續整合的有效性與即時性也絕對跟你團隊的分支策略有關。(建議基於主幹的開發)
4) 協作,如何透明順暢頻繁地溝通,又不會花太多無謂的溝通成本,如何確保大家的程式碼理解一致、閱讀無誤。extreme programming 裡面有非常多良好的實踐可以解決這些問題。
5) write clean code,高內聚、低耦合,職責明確,互動簡單,意圖清楚。(簡單設計simplicity 的四條原則)
6) 測試先行,test first, 其實是 think first, identifying requirements first. 在你動手寫產品程式碼之前,總要先搞懂需求的期望是什麼,需求怎樣叫完成。
要滿足使用者哪些情境,才叫符合預期。(這就是驗收測試驅動開發, ATDD)
這才是我們為何要寫程式的目標,接著以終為始,從 ATDD 往下 drill down 多個 TDD 循環以完成所有情境的程式碼,並在每個 TDD 循環中,一分不多一分不少的把力氣花在該花的地方上,並且在每一次的綠燈情況下進行重構。(包含測試程式)
這,才是實務上會 work 的 TDD,這才是為什麼 TDD 是種開發方法論,而不是測試方案。
7) 用測試描述行為,事實上 test-first + test as scenario, 怎麼把繁複的需求功能抽絲剝繭成關鍵情境,並進行排序來達到 baby step 的效果,到這邊6+7 就是 實例化需求(specification by examples)+驗收測試驅動開發(ATDD)+測試驅動開發(classic TDD, 紅燈、綠燈、重構)
8 ) 最後實現設計,意圖導向設計,重構、重構、重構,你得知道怎麼辨識出 code smell, 你得知道重構技巧,你得知道怎麼用最短時間、最低風險,正確地重構你的設計,來讓用的人很好用,看的人很好懂,改的人很好改。
這邊要避免不必要的過度設計,又是一整門學問了。(過度重構也是一種浪費,通常是以 #過度解耦 的模樣呈現。)
9) 從遺留代碼中學習,耐住性子去尊重這些遺留代碼。他們過去有其存在的價值與原因,至少你的薪水可能就是這堆線上又髒又臭的代碼在幫你賺的。
一定要壓抑住自己重寫系統或功能的衝動。
重寫跟重構不一樣的,重寫在實務跟價值上是不會 work 的。
而且,如果每次碰到遺留代碼就想重寫,你就永遠無法具備重構實務產品的能力。
當然,重構之前一定要有測試保護,這也是為什麼你該學的單元測試,是 #針對遺留代碼 如何優雅低風險低成本的加入單元測試。
沒有單元測試的保護,沒有單元測試提供的反饋(自己能做到的獲得最快的反饋實踐就是單元測試),就無法「快速進行較進階的重構」
—
當然,以上有蠻多是書裡沒提到的細節,也是我上課會提到、甚至設計成 workshop 的內容。
寫著寫著沒想到寫這麼多,沒辦法,共鳴點太多了,裡面真的沒啥廢話,也沒啥太打高空的東西。
都是扎扎實實該落地的實踐,要想當個基本功紮實、穩定輸出戰力,要想領的比別人多,就得比比別人具備更多能產生價值的能力。
不要再被你身邊的環境或公司受限住了,那都是你下意識給自己的藉口理由。
你覺得這些東西在你現在的公司工作用不上,所以你不想學。
但因為你不學、不會,又怎麼進得去把這些東西發揮地淋漓盡致的公司呢?人家怎麼會願意用你呢
👉 修改軟件的藝術,請參考 天瓏資訊圖書 上的介紹, https://www.tenlong.com.tw/products/9787115467768
※ 對實踐 5,6,7,8,9 有興趣,想透過實作了解的更透徹的朋友,可以參考底下兩門培訓:
1)演化式設計:測試驅動開發與持續重構 202009,https://dotblogs.com.tw/hatelove/2020/05/08/202009-Evolutionary-Development-TDD-and-Continuous-Refactoring
2)【針對遺留代碼加入單元測試的藝術】202011,https://dotblogs.com.tw/hatelove/2020/05/08/Unit-testing-effectively-with-legacy-code-202011
同時也有10000部Youtube影片,追蹤數超過2,910的網紅コバにゃんチャンネル,也在其Youtube影片中提到,...
「user story template」的推薦目錄:
- 關於user story template 在 91 敏捷開發之路 Facebook 的精選貼文
- 關於user story template 在 Taipei Ethereum Meetup Facebook 的精選貼文
- 關於user story template 在 AppWorks Facebook 的最讚貼文
- 關於user story template 在 コバにゃんチャンネル Youtube 的精選貼文
- 關於user story template 在 大象中醫 Youtube 的最讚貼文
- 關於user story template 在 大象中醫 Youtube 的最佳貼文
- 關於user story template 在 style-guide/agile-user-story.md at master - GitHub 的評價
- 關於user story template 在 Writing User Stories: It's Not as Difficult as You Think - Ascendle 的評價
user story template 在 Taipei Ethereum Meetup Facebook 的精選貼文
📜 [專欄新文章] Reason Why You Should Use EIP1167 Proxy Contract. (With Tutorial)
✍️ Ping Chen
📥 歡迎投稿: https://medium.com/taipei-ethereum-meetup #徵技術分享文 #使用心得 #教學文 #medium
EIP1167 minimal proxy contract is a standardized, gas-efficient way to deploy a bunch of contract clones from a factory.
1. Who may consider using EIP1167
For some DApp that are creating clones of a contract for its users, a “factory pattern” is usually introduced. Users simply interact with the factory to get a copy. For example, Gnosis Multisig Wallet has a factory. So, instead of copy-and-paste the source code to Remix, compile, key in some parameters, and deploy it by yourself, you can just ask the factory to create a wallet for you since the contract code has already been on-chain.
The problem is: we need standalone contract instances for each user, but then we’ll have many copies of the same bytecode on the blockchain, which seems redundant. Take multisig wallet as an example, different multisig wallet instances have separate addresses to receive assets and store the wallet’s owners’ addresses, but they can share the same program logic by referring to the same library. We call them ‘proxy contracts’.
One of the most famous proxy contract users is Uniswap. It also has a factory pattern to create exchanges for each ERC20 tokens. Different from Gnosis Multisig, Uniswap only has one exchange instance that contains full bytecode as the program logic, and the remainders are all proxies. So, when you go to Etherscan to check out the code, you’ll see a short bytecode, which is unlikely an implementation of an exchange.
0x3660006000376110006000366000732157a7894439191e520825fe9399ab8655e0f7085af41558576110006000f3
What it does is blindly relay every incoming transaction to the reference contract 0x2157a7894439191e520825fe9399ab8655e0f708by delegatecall.
Every proxy is a 100% replica of that contract but serving for different tokens.
The length of the creation code of Uniswap exchange implementation is 12468 bytes. A proxy contract, however, has only 46 bytes, which is much more gas efficient. So, if your DApp is in a scenario of creating copies of a contract, no matter for each user, each token, or what else, you may consider using proxy contracts to save gas.
2. Why use EIP1167
According to the proposal, EIP is a “minimal proxy contract”. It is currently the known shortest(in bytecode) and lowest gas consumption overhead implementation of proxy contract. Though most ERCs are protocols or interfaces, EIP1167 is the “best practice” of a proxy contract. It uses some EVM black magic to optimize performance.
EIP1167 not only minimizes length, but it is also literally a “minimal” proxy that does nothing but proxying. It minimizes trust. Unlike other upgradable proxy contracts that rely on the honesty of their administrator (who can change the implementation), address in EIP1167 is hardcoded in bytecode and remain unchangeable.
That brings convenience to the community.
Etherscan automatically displays code for EIP1167 proxies.
When you see an EIP1167 proxy, you can definitely regard it as the contract that it points to. For instance, if Etherscan finds a contract meets the format of EIP1167, and the reference implementation’s code has been published, it will automatically use that code for the proxy contract. Unfortunately, non-standard EIP1167 proxies like Uniswap will not benefit from this kind of network effect.
3. How to upgrade a contract to EIP1167 compatible
*Please read all the steps before use, otherwise there might have problems.
A. Build a clone factory
For Vyper, there’s a function create_with_code_of(address)that creates a proxy and returns its address. For Solidity, you may find a reference implementation here.
function createClone(address target) internal returns (address result){ bytes20 targetBytes = bytes20(target); assembly { let clone := mload(0x40) mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) mstore(add(clone, 0x14), targetBytes) mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) result := create(0, clone, 0x37) }}
You can either deploy the implementation contract first or deploy it with the factory’s constructor. I’ll suggest the former, so you can optimize it with higher runs.
contract WalletFactory is CloneFactory { address Template = "0xc0ffee"; function createWallet() external returns (address newWallet) { newWallet = createClone(Template); }}
B. Replace constructor with initializer
When it comes to a contract, there are two kinds of code: creation code and runtime code. Runtime code is the actual business logic stored in the contract’s code slot. Creation code, on the other hand, is runtime code plus an initialization process. When you compile a solidity source code, the output bytecode you get is creation code. And the permanent bytecode you can find on the blockchain is runtime code.
For EIP1167 proxies, we say it ‘clones’ a contract. It actually clones a contract’s runtime code. But if the contract that it is cloning has a constructor, the clone is not 100% precise. So, we need to slightly modify our implementation contract. Replace the constructor with an ‘initializer’, which is part of the permanent code but can only be called once.
// constructorconstructor(address _owner) external { owner = _owner;}// initializerfunction set(address _owner) external { require(owner == address(0)); owner = _owner;}
Mind that initializer is not a constructor, so theoretically it can be called multiple times. You need to maintain the edge case by yourself. Take the code above as an example, when the contract is initialized, the owner must never be set to 0, or anyone can modify it.
C. Don’t assign value outside a function
As mentioned, a creation code contains runtime code and initialization process. A so-called “initialization process” is not only a constructor but also all the variable assignments outside a function. If an EIP1167 proxy points to a contract that assigns value outside a function, it will again have different behavior. We need to remove them.
There are two approaches to solve this problem. The first one is to turn all the variables that need to be assigned to constant. By doing so, they are no longer a variable written in the contract’s storage, but a constant value that hardcoded everywhere it is used.
bytes32 public constant symbol = "4441490000000000000000000000000000000000000000000000000000000000";uint256 public constant decimals = 18;
Second, if you really want to assign a non-constant variable while initializing, then just add it to the initializer.
mapping(address => bool) public isOwner;uint public dailyWithdrawLimit;uint public signaturesRequired;
function set(address[] _owner, uint limit, uint required) external { require(dailyWithdrawLimit == 0 && signaturesRequired == 0); dailyWithdrawLimit = limit; signaturesRequired = required; //DO SOMETHING ELSE}
Our ultimate goal is to eliminate the difference between runtime code and creation code, so EIP1167 proxy can 100% imitate its implementation.
D. Put them all together
A proxy contract pattern splits the deployment process into two. But the factory can combine two steps into one, so users won’t feel different.
contract multisigWallet { //wallet interfaces function set(address[] owners, uint required, uint limit) external;}contract walletFactory is cloneFactory { address constant template = "0xdeadbeef"; function create(address[] owners, uint required, uint limit) external returns (address) { address wallet = createClone(template); multisigWallet(wallet).set(owners, required, limit); return wallet; }}
Since both the factory and the clone/proxy has exactly the same interface, no modification is required for all the existing DApp, webpage, and tools, just enjoy the benefit of proxy contracts!
4. Drawbacks
Though proxy contract can lower the storage fee of deploying multiple clones, it will slightly increase the gas cost of each operation in the future due to the usage of delegatecall. So, if the contract is not so long(in bytes), and you expect it’ll be called millions of times, it’ll eventually be more efficient to not use EIP1167 proxies.
In addition, proxy pattern also introduces a different attack vector to the system. For EIP1167 proxies, trust is minimized since the address they point to is hardcoded in bytecode. But, if the reference contract is not permanent, some problems may happen.
You might ever hear of parity multisig wallet hack. There are multiple proxies(not EIP1167) that refer to the same implementation. However, the wallet has a self-destruct function, which empties both the storage and the code of a contract. Unfortunately, there was a bug in Parity wallet’s access control and someone accidentally gained the ownership of the original implementation. That did not directly steal assets from other parity wallets, but then the hacker deleted the original implementation, making all the remaining wallets a shell without functionality, and lock assets in it forever.
https://cointelegraph.com/news/parity-multisig-wallet-hacked-or-how-come
Conclusion
In brief, the proxy factory pattern helps you to deploy a bunch of contract clones with a considerably lower gas cost. EIP1167 defines a bytecode format standard for minimal proxy and it is supported by Etherscan.
To upgrade a contract to EIP1167 compatible, you have to remove both constructor and variable assignment outside a function. So that runtime code will contain all business logic that proxies may need.
Here’s a use case of EIP1167 proxy contract: create adapters for ERC1155 tokens to support ERC20 interface.
pelith/erc-1155-adapter
References
https://eips.ethereum.org/EIPS/eip-1167
https://blog.openzeppelin.com/on-the-parity-wallet-multisig-hack-405a8c12e8f7/
Donation:
pingchen.eth
0xc1F9BB72216E5ecDc97e248F65E14df1fE46600a
Reason Why You Should Use EIP1167 Proxy Contract. (With Tutorial) was originally published in Taipei Ethereum Meetup on Medium, where people are continuing the conversation by highlighting and responding to this story.
👏 歡迎轉載分享鼓掌
user story template 在 AppWorks Facebook 的最讚貼文
昨天台灣大哥大發布訊息,自 2019 年 4 月 1 日起將聘任 AppWorks 創辦合夥人 Jamie 林之晨為總經理,長期關心 AppWorks 的朋友,或許會有些疑惑。其實不是 Jamie 換工作,而是 AppWorks 將與台灣大一起,挑戰一個放大 10 倍的計畫。在此跟大家分享 Jamie 的聲明,有更完整的敘述。
#以下是_Jamie_聲明全文
稍早台灣大哥大發布訊息,自 2019 年 4 月 1 日起將聘任為我為總經理,我的朋友們,以及長期關心我與 AppWorks 的媒體,一定會有許多疑惑,請容我在此統一向大家說明。
...Continue Reading
#EnglishBelow 稍早台灣大哥大發布訊息,自 2019 年 4 月 1 日起將聘任為我為總經理,我的朋友們,以及長期關心我與 AppWorks 的媒體,一定會有許多疑惑,請容我在此統一向大家說明。
首先,我不是接下了台灣大總經理的職位,而是接下了整合市值美金 120 億、營收美金 38 億的台灣大與市值美金 36 億、營收美金 25 億的 AppWorks Ecosystem,放大出 10 倍成果的任務。
這得從我的故事說起,如果您還沒聽過的話,我原本已經移民美國,和老婆小孩開心的住在紐約,2008 年,我在美看到 iPhone、Android 相繼問世,Facebook、Twitter 等社群媒體成為主流,意識到軟體的力量將越來越大,而硬體將越來越沒有價值,換言之,台灣的國際經濟地位將受到極大挑戰,因此決定舉家搬遷回台,推動台灣的轉型升級,以免我熱愛的福爾摩沙從世界經濟奇蹟變成失落的遺跡。
這是一個很大的決定,不僅我要放棄自己的美國夢,老婆、小孩都得跟著改變職涯、學涯,因此既然要做,就得發揮最大的 Impact。所以回台之後,我每天思考、決定、努力的,都是最大化我對台灣的貢獻。
因此這些年來我戴了很多帽子,表面看起來沒什麼相關性,但背後都有一個共同的目的,那就是推動台灣的改變。首先,我長期寫網誌、經營 Facebook 等網路社群、在《天下》等期刊寫專欄、出書、演講、接受採訪,心想的是分享新知、新觀念,散播進步需要的養分。
我與夥伴們成立 AppWorks,有系統的幫助年輕人創業,為的是培養千千萬萬帶領台灣前進的下一代生力軍。這也是為什麼 AppWorks 從 2010 年啟動半年一期的創業加速器,至今一直堅持免費提供。目前 AppWorks Accelerator 共畢業的 17 屆、925 位創業者,由他們成立的活躍企業高達 328 家,2018 年產值 760 億,提供 9,500 個工作機會,非常確切的為台灣貢獻一股向上動能。更重要的是,這些創業者們因 AppWorks 而相識相惜,形成一個緊密互助的網路,更是社會的長期資產。
當 AppWorks 在台灣站穩腳步,2014 年我們開始積極走訪東南亞,邀請優秀的東協創業者前來加入,希望透過串連跨國創業者網路,促進台灣的區域化,同時貢獻東協的數位發展。經過 5 年的推動,這個工作也有大幅進展,即將在 3 月進駐 AppWorks 的 33 組 AW#18 團隊,將有高達 19 組來自東南亞,包含他們在內,AppWorks 有 160 家企業在台灣以外的大東南亞市場有據點,形成一個真正區域化的網路。現在,來自台灣、香港、新加坡的 AppWorks 創業者要前往印尼、越南發展,可以很容易的找到 AppWorks 校友帶路,大大降低了區域化的門檻。
除了創業加速器,透過 AppWorks,我們同時努力創造更多台灣改變需要的新典範。以創業投資為例,我們 2012 年成功募集 3.2 億 Fund I,2014 年募得 15 億 Fund II,在 AppWorks 團隊的努力經營下,目前兩支基金的投資績效都是水準以上,其中 Fund II 至今的年化內部報酬率 (IRR) 達 29%,遠高於歐美同期創投基金的 Top Quartile (前四分之一) 指標。透過追求與國際一流基金同等的表現,我們希望促進台灣 LP (創投投資人的簡稱) 更有信心支持本土新興 GP (創投管理公司的簡稱),進而推動台灣創投業的復甦。
2016 年,我們出資成立 AppWorks School,每 4 個月一期,免費幫助年輕人透過實作學習程式、轉職工程師、加入成長中的數位行業,提升他們的職涯的同時,也為台灣貢獻人才。目前 School 已畢業 106 位學生,其中 85% 成功轉職,第一年起薪中位數達 67 萬。雖然杯水車薪,但我們希望拋磚引玉,刺激台灣教育的現代化,幫助年輕人準備好面對 AI 時代。
此外,AppWorks 雖然仍是中小企業,但受到的關注較多,因此也經常以身作則,為台灣業界示範新時代企業可以有的新思維。除了看齊國際優質創投的薪資獎金水準、年假無上限、自由選擇工作時間地點、新年假期長達三、四週外,我們更在日前啟動交棒計畫,讓年僅 30 歲的 Jessica 劉侊縈、40 歲的 Andy 蔡欣翰升任合夥人,希望激發台灣企業勇敢讓年輕人當家。
私部門之外,有機會推動台灣轉型的公領域活動,我也積極參與。2016 年,我從詹宏志先生手上接下 TiEA (台灣網際網路暨電子商務產業發展協會) 理事長,上任後便努力推動網路電商正名運動,成功說服了櫃買中心創立電子商務分類;2017 年起我開始擔任亞洲·矽谷民諮委共同召集人、數位國家諮詢委員、代表台灣參加每年四次的 ABAC (APEC Business Advisory Council) 會議,2018 年又奉總統之命擔任 APEC Vision Group 代表,與其他 20 會員國派出的先進,一起定義 APEC 未來的 20 年願景。這些雖然都是義務工作,但我都當作正職全力以赴,因為都有機會大大影響台灣的命運,以及在經濟領域的國際能見度。
最後,我去年決定再次舉家,準備遷往雅加達,同樣還是以為台灣貢獻出發。我觀察到 2.6 億人口的印尼正在快速崛起,短短 5 年內從有限的新創活動,到 4 隻本土獨角獸加 3 隻外來獨角獸的蓬勃景況,必須要幫助台灣抓住這個成長機會,但印尼商業生態與台灣大不相同,所以我決定進駐雅加達、深耕當地,希望能因此扮演帶領 AppWorks 新創進入印尼的嚮導,縮短我們與世界第四大國、東南亞第一大國的距離。這麼做得犧牲一些我在台灣的工作,但這些工作多半我的夥伴們可以承接,因此我便毅然開始行動。
講了這麼多,我其實只是希望您能了解,我大老遠從紐約搬回來的目的就是改變台灣,所以這些年來我做決定沒什麼懸念,因為不需要考慮自己的利益,只需要考慮在這個時間點,我做這件事情,是不是最能貢獻台灣。
如此我們便可以回到正題,這次的「台灣大 + AppWorks」專案。
不久前,蔡明忠董事長約我談話,詢問我有沒有興趣接下台灣大總經理的職位,一開始我其實是無法答應的,首先我已經決定搬去印尼,再來我也不確定接這個位子,跟貢獻台灣的關係。回去想了兩整天後,我有了答案,我跟蔡董事長說,必須有四個先決條件:
第一,結合台灣大和 AppWorks,用 AppWorks 生態系去幫助台灣大轉型為科技企業,同時以台灣大為平台去加速 AppWorks 新創的成長,因此創造更多成功的企業,為台灣示範成熟企業如何與新創實際合作;
第二,由 AppWorks 帶路,推動台灣大 + AppWorks 走出台灣,成為一個大東南亞科技集團,為台灣企業的區域化寫下典範,同時也成為能加速 AppWorks 新創區域化的大平台;
第三,以建立一個市值 1,000 億美金 (US$ 100B) 的科技集團為目標,創造第一個由台灣出發、真正達到國際級的非代工企業;
第四,所有因為台灣大 + AppWorks 集團未來的價值成長,公司依規定希望給予我個人的獎勵,要能全數由集團捐為公益使用,且專注在推動台灣的教育改革與電影工業上。
我跟蔡董事長說,如果以這四個目標為前提,那就值得我花 10 到 15 年的生命去推動。這基本上是我的夢幻清單,如果這麼做的話,能為台灣創造的貢獻,比 AppWorks 繼續獨立營運還會巨大許多,想不到蔡董事長毫不猶豫的答應。也因此,我回頭與 AppWorks 的夥伴們溝通,得到大家的支持後,我們決定一起接受這個挑戰。所以開頭我說,我不是接下了台灣大總經理的職位,而是接下了整合台灣大與 AppWorks,放大出 10 倍成果的任務。
當然,這不是一件容易的工作,發展新的商業模式,我或許有 20 年的創業、工作經驗作為後盾,但對於管理電信事業,對於領導一個 7,000 人的大集團,我有太多需要學習的地方,所以,我請蔡董事長務必持續扮演我的 Partner,在這個過程中一起確保電信本業的營運,好讓我們有最大的空間與時間,去爭取新事業的發展,為所有「台灣大 + AppWorks」的 Stakeholders,爭取最佳的長期利益。
未來幾年,將是電信業轉型的關鍵時期,去年 499 之亂加速電信用戶 ARPU (平均每戶營收) 的下滑,消費者換機時間拉長導致手機營收停滯,接下來資本支出是 4G 近 4 倍的 5G 即將到來,更讓電信長達 20 年紅利時代難以延續,AI、IoT、Blockchain、Cloud 等巨型典範轉移接連的到來,進一步逼迫電信業者不能繼續防守。
另一方面,電信業已經建立的品牌、長期客戶關係、大量用戶數據,卻是極有價值,可以更全面應用的資產。透過台灣大 + AppWorks 的結合,目前已經產生 760 億年營收的 AppWorks 的 328 家新創,以及未來將持續培養的更多新興企業,都有機會透過與台灣大的合作加速成長,而台灣大也能因此取得新的營收引擎,創造雙贏的局面。
所以,在可預見的未來,AppWorks 的方向不會改變,我們將持續邀請優秀的創業者加入,透過 AppWorks 原有的能量,以及新增的台灣大平台幫助他們。AppWorks 基金的營運也不會改變,事實上,加入了台灣大的能量,我們有信心能為 LP 們創造更好的財務、策略報酬。我的角色,除了新增台灣大總經理以外,也沒有改變,將持續擔任 AppWorks 的董事長、合夥人,戮力確保台灣大 + AppWorks 的整合能順利成功、長長久久,創造多贏。唯一改變的,大概是我的工作時間將會增加,因此要犧牲與家人的相處,在此先跟偉大的老婆、兩個可愛的兒子道歉,感謝他們對這個決定的支持與諒解。
至於搬遷至雅加達、引導更多 AppWorks 新創進軍印尼的計畫,很遺憾必須暫緩,所幸 AppWorks 的新任合夥人 Jessica (劉侊縈),已經承諾會扛起這個責任,相信在她的帶領下,AppWorks 的印尼計畫還是能夠大鳴大放、開花結果。
以上,就是針對此次台灣大 + AppWorks 的重大發展,向各位好友、媒體朋友的報告,懇求你們的支持。無論如何,我會持續為貢獻台灣而努力,希望我們這一輩的小孩們長大後,可以和我們一樣,以做台灣人為榮。
最後,預祝 您
新年快樂 諸凡順遂
助君張目 豬滿福保
Earlier today, Taiwan Mobile published an announcement communicating their intention to appoint me as the company’s general manager as of 4/1/2019. I’m sure this announcement may come as a surprise to many of my friends in the startup community, likely leaving you all with ample questions, concerns, and potentially even doubt. Let me take the opportunity to clarify the situation and explain the reasonings behind my decision for everyone.
Firstly, I must clarify that I am not merely taking over as GM of Taiwan Mobile, but taking on the bigger job of integrating Taiwan Mobile, a $12B market cap & $3.8B revenue company, and AppWorks, a $3.6B valuation & $2.5B revenue ecosystem, to amplify our impact by 10x.
But to adequately understand where we’re going, I think it’s important for everyone to know where we’ve come from. This begins with my story—for those of you that haven’t heard it before—which dates back to my time living in New York. It was around 2008 when I saw the launch of iPhone and Android, as well as the advent of Facebook, Twitter, etc, collectively catapulting social media into mainstream use. It was clear that software was increasingly taking over the world while the value of hardware was becoming more and more commoditized. This posed a dire existential threat to Taiwan, whose global economic contributions had been primarily driven by hardware and semiconductor manufacturing. This eventually prompted my resolve to move back to Taiwan and prevent our country from becoming a relic of the past.
This was by no means an easy decision. Not only did I have to give up my American dream, but my wife and child would have to completely uproot their lives, changing jobs and schools. It was a huge sacrifice on their end, so after moving back I dedicated myself to working hard every day to maximize my contribution to Taiwan and exert the greatest impact possible.
I have worn a lot of hats since, and it may seem that there is no correlation on the surface. But, there is indeed a common purpose behind them, which is to promote change in Taiwan. First of all, I have long written posts and columns in online communities such as my own blog, Facebook, and journals like “The Commonwealth Magazine,” while also giving speeches and interviews for a variety of outlets whenever possible. I see these activities as a way to share new knowledge, new ideas, and disseminate the nutrients needed for progress.
I set up AppWorks with my partners to systematically help young people start their own businesses and cultivate the next generation of business leaders that will steer Taiwan forward. That's why AppWorks started its semi-annual startup accelerator in 2010, and has been offering it for free ever since. With the addition of the latest batch AW#17, the AppWorks Ecosystem encompasses 328 active startups and 925 founders, having collectively generated US$ 2.5 billion in revenues and created 9,586 jobs—not an immaterial contribution to Taiwan’s economy needless to say. More importantly, we’ve created a tight-knit community where founders can form lifelong relationships, while seeking advice from both peers and mentors in good times and bad. I see that as a long-term value to society.
Once AppWorks took a firm foothold in Taiwan, we began targeting Southeast Asia in 2014 to invite outstanding ASEAN entrepreneurs to join us. We hope to promote Taiwan's regionalization through a network of international founders, and in turn, facilitate the development of SEA’s digital economy. We've made significant strides these past five years. AW#18 will kick off in March 2019, and consists of 33 teams, 19 of which hailing from countries across SEA and beyond. Spanning our entire ecosystem, AppWorks encompasses 160 companies currently operating in Southeast Asia, forming a truly regional network. Now, AppWorks founders from Taiwan, Hong Kong, and Singapore are expanding to Indonesia and Vietnam, and it is easy to find local AppWorks alumni to lead the way, greatly reducing the barriers for international expansion.
In addition to AppWorks Accelerator, we have been working hard to create more examples for a modern Taiwan. Taking venture capital as an example, we successfully raised US$ 11 million for Fund I in 2012 and US$ 50 million for Fund II in 2014. Under the efforts of the AppWorks team, the investment performance of the two funds is currently above the industry average, of which Fund II has achieved an annualized internal rate of return (IRR) of 29%. This is much higher than the top quartile of VCs in both Europe and the United States. By pursuing the same performance as international first-class funds, we hope to encourage Taiwanese LPs (short for venture capital investors) to be more confident in supporting local emerging GPs (short for venture capital management companies) and to promote the recovery and ultimate longevity of Taiwan's VC industry.
In 2016, we created AppWorks School with the aim of helping the younger generation pick up new skill sets, enhance their careers, and join the growing tech industry. The school offers four-month free programs and has now graduated 106 students, 85% of whom have secured jobs as software engineers, with a median starting salary of US$ 21,833. Although our scale is still tiny compared to larger institutes, we hope our efforts have inspired others to promote the modernization of Taiwan’s education system and equip young people with the necessary skills to thrive in the AI era.
In addition, although AppWorks is still a small to medium-sized enterprise, it has received a lot of attention. Therefore, it often leads by example and demonstrates how to apply new thinkings to modern corporate management. In addition to internationally-competitive salaries, our colleagues enjoy flexible working hours and locations, unlimited vacation days, and several weeks off around Chinese New Year. AppWorks also recently launched an internal promotion track, promoting two of our very own staff to partners, Jessica Liu (30) and Andy Tsai (40). We hope that this move will also create a ripple effect across traditional Taiwanese industries, inspiring more local enterprises to put their faith in younger leaders.
Alongside the private sector, I am also actively involved in promoting Taiwan’s transformation through public sector activities. In 2016, I took over as chairman of TiEA (Taiwan Internet and E-Commerce Association) from Mr. Hung-Tze Jan (詹宏志). After taking office, I have worked hard to promote our industry and successfully convinced government cabinet members to create a separate category for e-commerce companies, which didn’t previously exist in Taiwan’s stock market. Since 2017, I have been the co-convenor of the Asia-Silicon Valley Development Agency Advisory Committee, advisor of DIGI+ Taiwan, and the country’s member in ABAC (APEC Business Advisory Council). Most recently in 2018, I was appointed by the President to represent Taiwan in the APEC Vision Group, where 21 member states come together to define APEC's vision for the next 20 years. Although these are all voluntary work, I have treated them as full-time jobs because they produce opportunities that can greatly influence Taiwan’s future.
Finally, last year I was prepared to uproot my family again and move to Jakarta. With a population of 260 million people, I observed that Indonesia was a rapidly emerging economy, producing many areas where Taiwan and Taiwanese companies can contribute. In the span of just five years, Indonesia went from a barren startup landscape to producing four local unicorns and attracting the presence of three international unicorns. Although the opportunities are abundant, Indonesia’s ecosystem was much different from Taiwan’s, creating immense cultural, regulatory, and competitive barriers for Taiwanese companies. I had thus planned on relocating to Jakarta in hopes of better leading AppWorks startups into Indonesia and shortening our distance from the world’s fourth most populous country and GSEA’s biggest economy. I would have had to sacrifice some of my roles and responsibilities in my Taiwan, but I put faith in my partners and co-workers to fill the void.
With all that said, I want you to understand that the underlying mission to change Taiwan has never faltered. With this mission in mind, I’ve never hesitated in making decisions over the years because I’ve never needed to consider my own interests—but only the things I can do at the moment to best contribute to Taiwan and generate the most impact. It’s what prompted my resolution to move back from New York, my intent to move to Jakarta, and now my decision to take on this new opportunity with “Taiwan Mobile + AppWorks.”
Not long ago, the Chairman of Taiwan Mobile Daniel Tsai reached out and asked if I was interested in taking over as General Manager of Taiwan Mobile. At first, I was unable to take his offer because I was getting ready to move to Indonesia and I didn’t know how this would contribute to making Taiwan better. After allowing myself a few days to contemplate, I found an answer. I told Chairman Tsai that I would take on the position, but only if I can pursue these 4 ambitions:
First, leverage the AppWorks ecosystem to help transform Taiwan Mobile into a true technology company. At the same time, leverage Taiwan Mobile as a platform to accelerate the growth of AppWorks startups, thereby creating a successful collaboration template for other Taiwan & SEA large corporations to work with startups.
Second, with AppWorks leading the way, establish Taiwan Mobile + AppWorks into a regional technology group across Greater Southeast Asia, in turn, inspiring other Taiwanese companies to explore Southeast Asia as well as becoming a platform for startups to go regional.
Third, build Taiwan Mobile + AppWorks group to a market cap of US$ 100 billion and create the first non-OEM company that originates from Taiwan and truly reaches a global scale.
Fourth, throughout the process, all the bonuses I am entitled to shall be donated by the group to public welfare, focusing specifically on promoting education reform and the film industry in Taiwan.
I told Chairman Tsai if these are the goals, it’s worth dedicating the next 10 - 15 years of my life to achieve. This is basically my dream list. If I do this, the contribution to Taiwan and the GSEA region as a whole from the combined entity will be much greater than the continued independent operation of AppWorks. Chairman Tsai agreed on these four goals and gave me his promise, but it was still not a decision that I could make on my own--after all building AppWorks into what is it today was not something I did alone. Therefore, I went back to communicate with the AppWorks partners and team, and with everyone's support, we decided to accept this challenge together.
Thus, at the beginning of the post, I said, that I am not only taking over the position of Taiwan Mobile’s GM, but undertaking the task of integrating Taiwan Mobile and AppWorks to amplify our impact by 10x. Of course, developing a completely new business model is not an easy job. I may have 20 years of entrepreneurship and work experience under my belt, but I still have much to learn when it comes to managing a massive telecoms operation with over 7,000 people, most of whom are much more familiar with the industry than me. Therefore, I asked Chairman Tsai to act as my partner through the process to ensure the continued operations of the telecoms unit. This will enable more time and space to develop new businesses, benefiting all “Taiwan Mobile + AppWorks” stakeholders in the long run.
The telecoms industry will likely undergo a crucial transformation in the next few years. Last year’s “NT$499 war” accelerated the decline of telecom subscribers’ ARPU (average revenue per household). Longer replacement periods for smartphones have led to the stagnation of mobile phone revenues and the rollout of 5G will cost four times the capex as 4G. These factors all threaten the industry’s ability to maintain the fluid growth it’s experienced for the past 20 years. Furthermore, the arrival of paradigm shifting technologies such as AI, IoT, Blockchain, and Cloud have put all telecom operators on the defensive.
On the other hand, the telecoms industry has established brands, long-term customer relationships, and a massive amount of user data—all valuable assets that can be better maximized. Through the combination of Taiwan Mobile + AppWorks and the 328 startups that AppWorks has cultivated, all emerging startups will be able to look to the combined platform as a strategic engine for cooperation and growth. This is will also enable Taiwan to develop new sources of value creation--a win-win for both sides.
Therefore, in the foreseeable future, AppWorks will not change direction. We will continue to invite outstanding entrepreneurs to join our accelerator, staying true to the original ethos of AppWorks, while leveraging the new Taiwan Mobile platform to help them. The operation of AppWorks Funds will not change. In fact, with the backing of Taiwan Mobile’s resources, we are confident that we can create better financial and strategic rewards for LPs. My role at AppWorks will not change. I will continue to serve as a partner of AppWorks. I will ensure that the integration of Taiwan Mobile + AppWorks will be a successful, long-lasting win-win situation for all stakeholders involved. The only change is probably that my working hours will increase, effectively cutting into my family time. So first, I must apologize to my great wife and two lovely sons, and thank them for their continued support and understanding of this decision.
As for the plan to move to Jakarta and guide more AppWorks startups to enter Indonesia, regrettably it must be suspended. Fortunately, Jessica Liu, AppWorks’ newest partner, has promised to take up this responsibility. I believe that under her leadership, AppWorks' Indonesia initiative will still be able to make a big splash and develop fruitfully.
Hopefully, this post has provided you with all the relevant details regarding the Taiwan Mobile + AppWorks announcement. To friends and media, I sincerely appreciate your continued support. At any rate, I will continue to work hard to contribute to Taiwan. I hope that the children of our generation will grow up and be proud of being Taiwanese.
Finally, I wish everyone all the best. Have a wonderful and prosperous pig year!
user story template 在 コバにゃんチャンネル Youtube 的精選貼文
user story template 在 大象中醫 Youtube 的最讚貼文
user story template 在 大象中醫 Youtube 的最佳貼文
user story template 在 Writing User Stories: It's Not as Difficult as You Think - Ascendle 的推薦與評價
Feb 18, 2021 - User stories are the polar opposite of lengthy ... A user story boils down a desired feature into one short, ... User Story Template. ... <看更多>
user story template 在 style-guide/agile-user-story.md at master - GitHub 的推薦與評價
We're using the following template to create user stories. Since we have mentioned the type of user, the user story can refer to it with “I” ... ... <看更多>