Last active
February 15, 2021 22:16
-
-
Save fnbk/47c43f286771218b7e53eed70c847068 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# LOLA - Law of Leaky Abstraction | |
# | |
All abstractions are leaky. The outsider may need to know some insider information to use the abstraction. | |
An abstraction should not hide that which it abstracts, but rather simplify access to the underlying complexity. - Joel Spolsky | |
Example: | |
* Automobiles have abstractions for drivers: There is a steering wheel, accelerator and brake. This abstraction hides a lot of detail about what's under the hood: engine, cams, timing belt, spark plugs, radiator, etc. | |
* A 16 year old and a 80 year old can operate this complicated piece of machinery without really knowing much about how it works inside! | |
* If you rev up the engine too fast, you may do damage to it. If the engine block is too cold, the car may not start or it may have poor performance. If you use too much electricity (by using all at the same time: radio, headlights, heater, etc), then your engine may not start again. | |
* Although the abstraction hides a lot of complexity we still sometimes have to deal with the underlying details. | |
Key takeaways: | |
* Abstractions allow us to deal with new orders of complexity. | |
* Abstractions save us time working, but they don’t save us time learning. | |
* use the 80/20 rule: try to cover 80% of the usecases when creating an abstraction, be prepared to provide access to the underlying details for 20% of the time | |
# | |
# example | |
# | |
// ORM | |
public async List<string> AllUserNames() | |
{ | |
List<User> users = await db.Users.ToListAsync(); | |
return users.Select(user => user.Name); | |
} | |
// SQL | |
public async List<string> AllUserNames() | |
{ | |
List<string> usernames = new List<string>(); | |
SqlCommand command = new SqlCommand("SELECT name FROM tbl_users", sqlConnection); | |
SqlDataReader reader = command.ExecuteReader(); | |
while (reader.Read()) | |
{ | |
var name = reader.GetString(0); | |
usernames.Add(name); | |
} | |
return usernames; | |
} | |
# | |
# discussion | |
# | |
Example: You have 25 million users in your database. And you have two implementatins of the function AllUserNames(): | |
1) using an ORM framework | |
2) using native SQL statements | |
# bad example | |
* ORM: don't be suprised when it takes 100 sec to get the results | |
* ORMs are comfortably to use but may not cover all performance aspects | |
# good example | |
* SQL: takes 1 sec to get the results | |
* SQL: a lot of detail knowledge is needed | |
# exception to the rule | |
* 80% of the time: use ORM for the convenience methods | |
* 20% of the time: use SQL to deal with the underlying details | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment