Advertisement
Guest User

Untitled

a guest
Jul 22nd, 2017
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.13 KB | None | 0 0
  1. know why **Spaghetti Code** is less than ideal<br/>
  2. **spaghetti code** is difficult to read, maintain, and scale, and for those reasons and more, we need a better approach to architecting our applications.
  3.  
  4. Solution to Shopping List App:
  5. ```
  6. $(function(){
  7. $('#js-shopping-list-form').submit(function(event) {
  8. event.preventDefault();
  9. const listItem = $('.js-shopping-list-entry').val();
  10.  
  11. $('#shopping-list-entry').val('');
  12.  
  13. $('.shopping-list').append(
  14. `<li>
  15. <span class="shopping-item">${listItem}</span>
  16. <div class="shopping-item-controls">
  17. <button class="shopping-item-toggle">
  18. <span class="button-label">check</span>
  19. </button>
  20. <button class="shopping-item-delete">
  21. <span class="button-label">delete</span>
  22. </button>
  23. </div>
  24. </li>`);
  25. });
  26.  
  27. $('.shopping-list').on('click', '.shopping-item-delete', function(event) {
  28. $(this).closest('li').remove();
  29. });
  30.  
  31. $('.shopping-list').on('click', '.shopping-item-toggle', function(event) {
  32. $(this).closest('li').find('.shopping-item').toggleClass('shopping-item__checked');
  33. });
  34.  
  35. });
  36. ```
  37. it's important to develop good coding habits and a sense of what makes for good code architecture. So with no further ado, here are some of the deficiencies with this solution:
  38.  
  39. **You have to read every line of code to understand how the app works.**<BR/>
  40. The app is composed entirely of a single, anonymous document ready function that has jQuery event listeners for submit and click events that in turn call additional anonymous functions, which appear to do something to the DOM, but without inspecting the HTML, it's hard to know what they do.
  41.  
  42. **It's difficult to reason about the shopping list data**<br/>
  43. The problem is that the data for the shopping list itself is stored entirely in the DOM. The only way you can understand the overall state of the shopping list at any time is by inspecting each list item in the DOM. And to make matters worse, the problem you're trying to diagnose involves the DOM being wrong about displaying the list! Ideally, we need to establish** one part of our code for storing the underlying data for our shopping list**, and **then have a different part of our code deal with how that code is rendered in the DOM**. This will allow us to ask and answer questions about how what the DOM is displaying corresponds (or doesn't) to the data model.
  44.  
  45. **Spaghetti code doesn't scale**
  46.  
  47. Our shopping list app is about as simple as apps come in terms of what users can do with it: they can read a shopping list, add items to it, delete them, and check and uncheck them.
  48. Now imagine a complex app like Facebook or Gmail implemented in a single document ready function. The fact is that neither Facebook nor Gmail would be working apps if they were built with spaghetti code.
  49.  
  50. ### Clearly describing your application with user stories <br/>
  51. Before opening your text editor, it's critical to get a clear picture of what you're building. That means coming up with clear, concise statements that describe what the app you're building will do. These statements will tell you what you need to build and when a particular feature of the app is complete. They also provide a common language for speaking with non-technical stakeholders on a project.
  52.  
  53. Here's how we could break down our shopping list:
  54.  
  55. * A shopping list should be rendered to the page
  56. * You should be able to add items to the list
  57. * You should be able to check items on the list
  58. * You should be able to delete items from the list
  59. These statements are examples of user stories, which are short, plain language descriptions of what a user should be able to do with an app. User stories can be written by and discussed by technical and non-technical stakeholders. Notice that these user stories don't say anything about **how** the app is to be implemented. Instead they focus on **what** the app should do. Recall that we made a similar observation about how well-named, small functions allow a coder to quickly understand what an app does without having to look at how each function is implemented. This happy coincidence is one we can take advantage of as we start architecting our application.
  60.  
  61. ### From user stories to function stubs with pseudocode <br/>
  62. We're going to write function stubs. These functions will have names but inside of each one, we won't add any working code. Instead, we'll just add a description of what the code should do. We'll also go ahead and hook these functions up to a document ready function, since we know we'll definitely need that.
  63. ```
  64. function renderShoppingList() {
  65. // this function will be repsonsible for rendering the shopping list in
  66. // the DOM
  67. console.log('`renderShoppingList` ran');
  68. }
  69. function handleNewItemSubmit() {
  70. // this function will be responsible for when users add a new shopping list item
  71. console.log('`handleNewItemSubmit` ran');
  72. }
  73. function handleItemCheckClicked() {
  74. // this funciton will be reponsible for when users click the "check" button on
  75. // a shopping list item.
  76. console.log('`handleItemCheckClicked` ran');
  77. }
  78. function handleDeleteItemClicked() {
  79. // this function will be responsible for when users want to delete a shopping list
  80. // item
  81. console.log('`handleDeleteItemClicked` ran')
  82. }
  83. function handleShoppingList() {
  84. // render the shopping list
  85. // handle when a new item is submitted
  86. // handle when an item is deleted
  87. // handle when an item is checked/unchecked
  88. }
  89. ```
  90.  
  91. Now lest fully implement the `handleShoppingList` function:
  92. ```
  93. function renderShoppingList() {
  94. // render the shopping list in the DOM
  95. console.log('`renderShoppingList` ran');
  96. }
  97. function handleNewItemSubmit() {
  98. // listen for users adding a new shopping list item, then add
  99. // to list and render list
  100. console.log('`handleNewItemSubmit` ran');
  101. }
  102. function handleItemCheckClicked() {
  103. // listen for users checking/unchecking list items, and
  104. // render them checked/unchecked accordingly
  105. console.log('`handleItemCheckClicked` ran');
  106. }
  107. function handleDeleteItemClicked() {
  108. // Listen for when users want to delete an item and
  109. // delete it
  110. console.log('`handleDeleteItemClicked` ran')
  111. }
  112. function handleShoppingList() {
  113. renderShoppingList();
  114. handleNewItemSubmit();
  115. handleItemCheckClicked();
  116. handleDeleteItemClicked();
  117. }
  118. $(handleShoppingList);
  119. ```
  120. Perform console.log on the above code and in browser [developer tools] this proves that everything is wired up correctly.
  121.  
  122.  
  123. ### Modeling our data <br/>
  124. What we need is a single source of truth about the state of our shopping list. We want to be able to store that data some place, and what the user sees in the DOM should ultimately be a reflection of the current state of our data model.
  125. Specifically, we need a way of modeling a shopping list. How can we best store data about a shopping list?
  126. The name shopping list itself already implies that we'll probably want to use a JavaScript array. That would allow us to store multiple list items, add items, and delete them.
  127. Each item on the list needs at least two attributes: the item name, and whether or not it is currently checked. We say "at least two" because there's arguably a third attribute we need: each item needs a unique identifier that we can use to choose a specific item and delete or check/uncheck it. But since we're using an array, we can use each item's array index as its id (for instance, the first item in our shopping list array will be at index 0).
  128. ```
  129. const STORE = [
  130. {name: "apples", checked: false},
  131. {name: "oranges", checked: false},
  132. {name: "milk", checked: true},
  133. {name: "bread", checked: false}
  134. ];
  135. ```
  136. `STORE` is a constant and that does **NOT** mean that the shopping list array itself should not be altered, that would be useless for our app...it's OK to alter the underlying array, it's NOT ok to reassign the variable name to a new value.
  137. // okay
  138. `STORE.push({name: "chocolate", checked: true});`
  139.  
  140. // not okay!
  141. `STORE = {foo: 'bar'};`
  142.  
  143. A final note about `STORE`. In JavaScript, complex data types (aka, objects and arrays) are passed by *reference*, not by *value*. That means that if you pass an array or object to a function as an argument, and the function mutates it, the value of the original variable outside of the function will also be mutated.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement