Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
That Fresh Mobile Smell
Search
Fred Medlin
February 20, 2014
Programming
1
61
That Fresh Mobile Smell
Android Presenter First talk at TriDroid West.
Fred Medlin
February 20, 2014
Tweet
Share
Other Decks in Programming
See All in Programming
マッチングアプリにおけるフリックUIで苦労したこと
yuheiito
0
190
猫と暮らす Google Nest Cam生活🐈 / WebRTC with Google Nest Cam
yutailang0119
0
170
Modern Angular with Signals and Signal Store:New Rules for Your Architecture @enterJS Advanced Angular Day 2025
manfredsteyer
PRO
0
270
ふつうの技術スタックでアート作品を作ってみる
akira888
1
1.3k
PHPでWebSocketサーバーを実装しよう2025
kubotak
0
320
MDN Web Docs に日本語翻訳でコントリビュートしたくなる
ohmori_yusuke
1
130
スタートアップの急成長を支えるプラットフォームエンジニアリングと組織戦略
sutochin26
1
7.3k
システム成長を止めない!本番無停止テーブル移行の全貌
sakawe_ee
1
360
「テストは愚直&&網羅的に書くほどよい」という誤解 / Test Smarter, Not Harder
munetoshi
0
200
ソフトウェア設計とAI技術の活用
masuda220
PRO
17
3.8k
#QiitaBash MCPのセキュリティ
ryosukedtomita
1
1.5k
Goで作る、開発・CI環境
sin392
0
260
Featured
See All Featured
Measuring & Analyzing Core Web Vitals
bluesmoon
7
520
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
161
15k
The Invisible Side of Design
smashingmag
301
51k
Visualization
eitanlees
146
16k
What's in a price? How to price your products and services
michaelherold
246
12k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
126
53k
Into the Great Unknown - MozCon
thekraken
40
1.9k
Optimising Largest Contentful Paint
csswizardry
37
3.3k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
282
13k
Become a Pro
speakerdeck
PRO
29
5.4k
RailsConf 2023
tenderlove
30
1.1k
Gamification - CAS2011
davidbonilla
81
5.4k
Transcript
That Fresh Mobile Smell ! TriDroidWest 2.20.2014 Fred Medlin
None
None
None
NOT BUGS SYMPTOM OF A DEEPER PROBLEM WEAKNESS THAT SLOWS
DOWN DEVELOPMENT CODE SMELLS
976 LINES KNOWS TOO MUCH DOES TOO MUCH LARGE CLASS
=> GOD OBJECT
BUSINESS DATA AND LOGIC MODEL USER STORY BEHAVIOR USER INTERACTIONS
PRESENTER VIEW PRESENTER FIRST
BUSINESS DATA AND LOGIC MODEL USER STORY BEHAVIOR USER INTERACTIONS
PRESENTER VIEW PRESENTER FIRST
BUSINESS DATA AND LOGIC MODEL USER STORY BEHAVIOR USER INTERACTIONS
PRESENTER VIEW PRESENTER FIRST
HOW IT’S DONE 1.Start with a user story 2.Stub a
presenter 3.Write interface methods for model and view 4.Add presenter tests to confirm the methods were called
1. USER STORY Using my current latitude and longitude, find
and display the nearest geo-tagged wikipedia entry.
2. STUB PRESENTER public class GeoWikiPresenter {! private GeoWikiModel model;!
private GeoWikiView view;! ! public GeoWikiPresenter(GeoWikiModel model, GeoWikiView view) {! this.model = model;! this.view = view;! }! }!
3. MODEL/VIEW INTERFACE METHODS public interface GeoWIkiModel {! !void findLocation();!
!void queryArticles(float latitude, float longitude);! }! ! public interface GeoWikiView {! !void showProgress();! !void hideProgress();! !void displayPage(String url);! }!
4. PRESENTER TESTS public class GeoWikiPresenterTest {! !@Mock GeoWikiModel model;!
!@Mock GeoWikiView view;! !GeoWikiPresenter presenter;! ! !@Before! !public void setup() {! !!Mockito.initAnnotations(this);! !!presenter = new GeoWikiPresenter(model, view);! !}! }!
4. PRESENTER TESTS (2) @Test! ! public void searchesForLocation() {!
! ! verify(model).findLocation();! ! ! verify(view).showProgress();! ! }! ! ! @Test! ! public void queryWikiLocation() {! ! ! presenter.onLocationFound(new FoundLocationEvent(lat, lon));! ! ! verify(model).queryArticles(lat, lon);! ! }!
4. PRESENTER TESTS (3) public class GeoWikiPresenter {! private GeoWikiModel
model;! private GeoWikiView view;! ! public GeoWikiPresenter(GeoWikiModel model, GeoWikiView view) {! this.model = model;! this.view = view;! model.findLocation();! view.showProgress();! ! @Subscribe! public void onLocationFound(FoundLocationEvent event) {! ! model.queryArticles(event.getLatitude(), event.getLongitude());! }! ! @Subscribe! public void onArticleFound(FoundArticleEvent event) {! ! view.hideProgress();! ! view.displayPage(event.getUrl());! }! }! }!
None
3. MODEL/VIEW INTERFACE METHODS public interface GeoWIkiModel {! !void findLocation();!
!void queryArticles(float latitude, float longitude);! }! ! public interface GeoWikiView {! !void showProgress();! !void hideProgress();! !void displayPage(String url);! }!
FRESH public class MainActivity extends Activity {! ! ! GeoWikiPresenter
presenter;! ! ! @Override! ! public void onCreate(Bundle savedInstanceState) {! ! ! super.onCreate(savedInstanceState);! ! ! setContentView(R.layout.activity_main);! ! ! presenter = new GeoWikiPresenter(new GeoWikiModelImpl(), new GeoWikiViewImpl());! ! }! ! ! @Override! ! public void onPause() {! ! ! super.onPause();! ! ! BusProvider.unregister(presenter);! ! }! ! ! @Override! ! public void onResume() {! ! ! super.onPause();! ! ! BusProvider.register(presenter);! ! }! }!
• Traditional SW mistake • Focuses on invisible things MODEL
FIRST • Seems reasonable, but… • Views attract strong feeling • High rate of changes • Hard to test VIEW FIRST ALTERNATIVES?
None
Fred Medlin
[email protected]
@fmedlin
LINKS Mockito - https://code.google.com/p/mockito/ Otto - http://square.github.io/otto/
All photos via Creative Commons Licenses from flickr.com ! -
Attribution-NonCommercial-NoDerivs 2.0 Generic (CC BY-NC-ND 2.0) - (mbshane) http://www.flickr.com/photos/mbshane/3165456548/ - (reid-bee) http://www.flickr.com/photos/reid-bee/5521024764/ - (captain_chickenpants) http://www.flickr.com/photos/captain_chickenpants/320441513/ - (RosenRakuen) http://www.flickr.com/photos/91134569@N05/8365293556/ ! Attribution-NonCommercial-ShareAlike 2.0 Generic (CC BY-NC-SA 2.0) - (clintjcl) http://www.flickr.com/photos/clintjcl/2708117471/ ! Attribution 2.0 Generic (CC BY 2.0) - (jeffreyww) http://www.flickr.com/photos/jeffreyww/4867984686/ - (quietlyurban.com) http://www.flickr.com/photos/83118222@N06/9689975423/ ! Attribution-NonCommercial 2.0 Generic (CC BY-NC 2.0) - (hatalmas) http://www.flickr.com/photos/hatalmas/6094281702/ PHOTO CREDITS