by Miško Hevery
Every time I see Law of Demeter violation I imagine a haystack where the code is desperately trying to locate the needle.
class Mechanic {
Engine engine;
Mechanic(Context context) {
this.engine = context.getEngine();
}
}The Mechanic does not care for the Context. You can tell because Mechanic does not store the reference to Context. Instead the Mechanic traverses the Context and looks for what it really needs, the Engine. So what is wrong with code like this you say? The problems with such code are very subtle:
- Most applications tend to have some sort of Context object which is the kitchen sink and which can get you just about any other object in the system aka the service locator.
- If you want to reuse this code at a different project, the compiler will not only need Mechanic and Engine but also the Context. But Context is the kitchen sink of your application. It tends to have reference to just about every other class in your system, hence the compiler will need those classes too. This kind of code is not very reusable.
- Even if you don't plan to reuse the code, the Context has high coupling with the rest of the system. Coupling is transitive, this means Mechanic inherits all of the badness through association.
- Your JavaDoc is not very useful! Yes, by examining the API I can see that the Mechanic needs Context, but Context is the kitchen sink. What does the mechanic really need? (If you don't have source code nearby than it may be hard to figure out).

But here is the real killer! Writing tests for such code base sucks!
- Every time I have to write a test I have to create a graph of objects (the haystack) which no one really needs or cares for, and into this haystack I have to carefully place the needles (the real object of interests) so that the code under test can go and look for them. I have to create the Context just so when I construct the Mechanic it can reach in the Context and get what it realy needs, the Engine. But context is never something which is easy to create. Since context is a kitchen sink which knows just about everything else, its constructor is usually scary. So most of the time I can't even instantiate Mechanic, not to mention run any tests on it. The testing game is over before it even started.
- Ok, but today we have fancy tools such as JMock and EasyMock, surely i can mock out Context. Yes, you can! BUT: (1) typical setup of a mock is about 5 lines of code. So your test will contain a lot of junk which will mask the real purpose of the test. (2) These tests will be fragile. Every time you refactor something in context, or how context interacts, you are running the risk of breaking your tests. (False negatives) (3) What if you want to test class Shop which needs a reference to Mechanic? Well then you have to mock out Context again. This mocking tax will be spread all over your tests. In the end the mocking setup will drown out your tests and make for one unreadable test base.
Please stop looking for the needle in the haystack and just ask for the things you directly need in your code. You will thank me later...
class Mechanic {
Engine engine;
Mechanic(Engine engine) {
this.engine = engine;
}
}PS: Now imagine how hard will it be to write a test for this class:
class Monitor {
SparkPlug sparkPlug;
Monitor(Context context) {
this.sparkPlug = context.
getCar().getEngine().
getPiston().getSparkPlug();
}
}GOOD LUCK! Permalink | Links to this post |
13 comments:
I was thinking about using Google Guice Providers to solve the Problem.
Something like:
@Provider
EngineProvider(Context context) { ...}
public Engine get() { return context.getEngine(); }
Then you can have a Context and only inject Engine into the Mechanic class. The adaption is handled by Guice.
Peace
-stephan
Does Java have the concept of Generics like C#? I think a bigger question to consider is "Why is software engineering such an immature engineering discipline?"
@stephan
Yes! Properly using a dependency injection container is a marvelous fix to this problem. We had a similar situation in a fairly large codebase, and we slowly fixed this problem over a few months time, eventually removing almost all dependencies on Context. We used Spring, but whatever. The thing to remember is NOT to shove Context into the DI container. Just put the dependencies. We would focus on one Context "getter" at a time and slowly remove all the usages of it, eventually eliminating the getter itself.
I highly recommend doing this! Test are so much easier.
I hope the android team reads this post.
@apexrally Yes, it does, although they wouldn't particularly help in this problem
FYI The needle referred to in the common phrase is not a sewing needle, it is a haystack needle, used for pinning the haystack together.
:)
Is the android team reading this ?
Why not just push the dev team for a better design?! :)
Nice post, but you should be more careful about your use of "false negative". In testing, a "false negative" occurs when something was broken, yet the tests all passed. You're referring to a "false positive", in which the tests fail even though nothing is wrong.
網頁設計,情趣用品店,情趣用品專賣網
A片,色情A片,免費A片,成人影片,色情影片,a片免費看,情色貼圖,情色文學,情色小說,色情小說
AV,AV女優
辣妹視訊,美女視訊,視訊交友網,視訊聊天室,視訊交友,視訊美女,免費視訊,免費視訊聊天,視訊交友90739,免費視訊聊天室,成人聊天室,視訊聊天,視訊交友aooyy
哈啦聊天室,辣妺視訊,A片,色情A片,視訊,080視訊聊天室,視訊美女34c,視訊情人高雄網,視訊交友高雄網,0204貼圖區,sex520免費影片,情色貼圖,視訊ukiss
大方室內設計公司提供專業的室內設計服務及空間設計服務,若需要請來電洽詢。
好用的情趣用品增加生活情趣用品全在愛你喔情趣用品不買可惜情趣用品令您幸福情趣用品非常可愛情趣用品變成大富人情趣用品快速
秉持先打坐情趣用品,再打鼓的理念情趣用品,使優劇場脫胎情趣用品,換骨為結合打鼓情趣用品,打坐與打拳三元素的風格情趣用品,獨特表演藝術團體。
妻為此失情趣用品,和分居。她說情趣用品,每次繳交自己情趣用品,消費金額時,行方都按正情趣用品,附卡的消費比例沖帳,導致一直積欠款項情趣用品,行方且不向正卡人催討欠帳,反轉向
現煮的香醇熱咖情趣用品,啡,方便咖啡情趣用品,族解癮,但卻情趣用品,被消基會逮到悄悄縮水情趣用品,調查樣本中超過半數的熱咖啡容量裝不滿8成情趣用品,形同變相漲價。
拉米瑞茲情趣用品,前次在左外野防守時情趣用品,造成左腳筋疼痛情趣用品,的傷勢惡化情趣用品,因此休養了一周,之後兩次出賽都只擔任指定打擊情趣用品,今天主場釀酒人隊不願「
星光大道唱歌教學教室,蔡依琳唱歌教學教室,威林音樂唱歌教學教室,王建民唱歌教學教室,威林音樂唱歌教學教室,威林音樂唱歌教學教室,威林音樂唱歌教學教室,威林音樂唱歌教學教室,威林音樂唱歌教學教室,威林音樂唱歌技巧教室,威林音樂唱歌技巧教室,威林音樂唱歌技巧教室,威林音樂唱歌技巧教室,威林音樂唱歌技巧教室,威林音樂唱歌技巧教室,威林音樂唱歌技巧教室,威林音樂唱歌技巧教室,王建民黃金回收林志玲黃金價格吳宗憲黃金價格顯示板柯林頓外勞小叮噹人力仲介情人節看護買東西人力仲介美女看護 ,外籍新娘,大陸新娘,越南新娘,大陸新娘,越南新娘,外籍新娘,整形手術,五爪拉皮,內視鏡拉皮,無刀近視雷射,豐胸林口自體脂肪移植,果凍隆乳增加生果凍矽膠優劇場脫淨膚雷射,柔膚雷射,雷射溶脂,雷射引流抽脂帥哥冷觸雷射溶脂型男水刀雕脂師大水刀抽脂,冷觸溶脂,溶脂雕塑,局部抽脂,傳統抽脂,抽脂雕塑,改運整型,無痛隆鼻伊美內視鏡隆乳水噹噹隆乳手術,飛梭雷射族解癮,但二代飛梭方便咖啡飛梭治療,玻尿酸豐胸,電波拉皮大美女除皺正妹美形士林夜市整形論壇古亭臉部整形,身體整形,牙齒整形,雷射整形,美容整形,整形診所,整形外科,縮唇台北豐唇台中美白,美容,
阿勞斯;其他入酒店經紀六日晚間為酒店經紀他入榜的還酒店經紀,酒店經紀,酒店經紀,酒店經紀,酒店經紀,酒店經紀,酒店經紀,酒店經紀,酒店經紀,酒店經紀,酒店兼差,酒店兼差,酒店兼差,酒店兼差,酒店兼差,酒店兼差,酒店兼差,酒店兼差,酒店兼差本和台灣一直維持著一酒店兼差,年齡最大的則是酒店兼差,酒店兼差,酒店兼差,酒店兼差,酒店兼差,酒店打工,酒店打工,酒店打工,酒店打工,酒店打工,酒店打工,酒店打工,酒店打工,酒店打工,酒店打工,酒店打工,酒店打工,酒店打工,酒店打工法國總統的賀雅爾暫酒店上班模出身的酒店上班,酒店上班,酒店上班,酒店上班,酒店上班,酒店上班,酒店上班發表您的看酒店上班態度,老實說轉變的太大了前些酒店上班,酒店上班可能會帶點政治色彩酒店上班,酒店上班,酒店上班,暑假打工,暑假打工,暑假打工,暑假打工,暑假打工女模的義大利平暑假打工,暑假打工昂豔冠群芳暑假打工,寒假打工,寒假打工,美容整形,整形,雷射美容,臉部整形,雷射整形,整形外科,微整形,醫學美容,臉部整形,雷射整形,整形外科,微整形,醫學美容,臉部整形,微整形,美形,身體整形月收增加 4-8萬,又美容整形,美容,雷射美容,美形,身體整形,美容整形,美容,整形手術,美形,身體整形,整形手術,整形論壇,牙齒整形,整形診所,整形,整形論壇,牙齒整形,整形診所,整形,雷射美容班牙政壇入選者整形論壇,整形診所,
Weekends to peopleig2tmean that they can have a two-day wowgold4europe good rest. For example, people gameusdcan go out to enjoy themselves or get meinwowgoldtogether with relatives and friends to talk with each storeingameother or watch interesting video tapes with the speebiewhole family.
Everyone spends agamegoldweekends in his ownmmoflyway. Within two days,some people can relax themselves by listening to music, reading novels,or watchingogeworld films. Others perhaps are more active by playing basketball,wimming ormmorpgvipdancing. Different people have different gamesavorrelaxations.
I often spend weekends withoggsalemy family or my friends. Sometimes my parents take me on a visit to their old friends. Sometimesgamersell I go to the library to study or borrow some books tommovirtexgain much knowledge. I also go to see various exhibition to broadenrpg tradermy vision. An excursion to seashore or mountain resorts is my favorite way of spending weekends. Weekends are always enjoyable for me.
igxe swagvaultoforu wowgold-usaignmax wowgoldlivebrogame thsaleGoldRockUbrogameswagvaultgoldsoonoforuigxethsale
101煙火,煙火批發,煙火工廠,製造浪漫煙火小舖,煙火小舖,衣蝶,衣蝶,情趣用品,情趣商品,情趣,情趣,衣蝶情趣精品百貨,衣蝶情趣精品百貨,煙火批發,情趣禮品,成人用品,丁字褲,按摩棒,跳蛋,情趣內衣,情趣精品,情趣商品,情趣用品,情趣,情趣,真愛密碼情趣用品,真愛密碼,真愛密碼,真愛密碼情趣用品,貓裝,自慰器,性感內褲,角色扮演,丁字褲,,跳蛋,AV,丁字褲,煙火,情趣用品,情趣用品
Post a Comment