Skip to content

Instantly share code, notes, and snippets.

@Kjaer
Last active April 9, 2023 00:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kjaer/8d71bd38bab1ee3f89a01f84c284bca1 to your computer and use it in GitHub Desktop.
Save Kjaer/8d71bd38bab1ee3f89a01f84c284bca1 to your computer and use it in GitHub Desktop.
Clean + MVVM Architecture
Display the source blob
Display the rendered blob
Raw
<?xml version="1.0" encoding="UTF-8"?>
<svg width="2574px" height="1010px" viewBox="0 0 2574 1010" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Concepts</title>
<g id="Concepts" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M291,119.886751 L577.752485,285.443376 L577.752485,616.556624 L291,782.113249 L4.24751514,616.556624 L4.24751514,285.443376 L291,119.886751 Z" id="Polygon" stroke="#55D4F5" stroke-width="5"></path>
<path d="M1129,119.886751 L1415.75248,285.443376 L1415.75248,616.556624 L1129,782.113249 L842.247515,616.556624 L842.247515,285.443376 L1129,119.886751 Z" id="Polygon-Copy-3" stroke="#55D4F5" stroke-width="5"></path>
<path d="M2134,66.7320508 L2278.85829,150.366025 L2278.85829,317.633975 L2134,401.267949 L1989.14171,317.633975 L1989.14171,150.366025 L2134,66.7320508 Z" id="Polygon-Copy-3" stroke="#55D4F5" stroke-width="3"></path>
<polygon id="Polygon" fill="#55D4F5" points="436 403 545.119201 466.25 545.119201 592.75 436 656 326.880799 592.75 326.880799 466.25"></polygon>
<polygon id="Polygon-Copy-4" fill="#55D4F5" points="1274 403 1383.1192 466.25 1383.1192 592.75 1274 656 1164.8808 592.75 1164.8808 466.25"></polygon>
<polygon id="Polygon-Copy-2" fill="#55D4F5" points="303.5 174 413.052214 237 413.052214 363 303.5 426 193.947786 363 193.947786 237"></polygon>
<polygon id="Polygon-Copy-5" fill="#55D4F5" points="1141.5 174 1251.05221 237 1251.05221 363 1141.5 426 1031.94779 363 1031.94779 237"></polygon>
<path d="M53.4297578,538 C57.9950911,538 61.8884245,536.88 65.1097578,534.64 C68.3310911,532.4 70.7737578,529.168 72.4377578,524.944 C74.1017578,520.72 74.9337578,515.664 74.9337578,509.776 C74.9337578,504.485333 73.6110911,500.421333 70.9657578,497.584 C68.3204245,494.746667 64.5017578,493.328 59.5097578,493.328 L59.5097578,493.328 L46.3897578,493.328 L38.9017578,538 L53.4297578,538 Z M53.6217578,530.512 L49.5897578,530.512 L54.5177578,500.816 L58.6777578,500.816 C60.9390911,500.816 62.6244245,501.402667 63.7337578,502.576 C64.8430911,503.749333 65.3977578,505.552 65.3977578,507.984 C65.3977578,509.349333 65.2697578,510.8 65.0137578,512.336 L65.0137578,512.336 L63.6697578,520.4 C63.1150911,523.856 62.0164245,526.405333 60.3737578,528.048 C58.7310911,529.690667 56.4804245,530.512 53.6217578,530.512 L53.6217578,530.512 Z M93.5571719,538.768 C98.0798385,538.768 101.845172,537.424 104.853172,534.736 C107.861172,532.048 110.069172,528.485333 111.477172,524.048 C112.885172,519.610667 113.589172,514.725333 113.589172,509.392 C113.589172,504.016 112.309172,499.866667 109.749172,496.944 C107.189172,494.021333 103.285172,492.56 98.0371719,492.56 C93.5145052,492.56 89.7491719,493.904 86.7411719,496.592 C83.7331719,499.28 81.5251719,502.842667 80.1171719,507.28 C78.7091719,511.717333 78.0051719,516.602667 78.0051719,521.936 C78.0051719,527.312 79.2851719,531.461333 81.8451719,534.384 C84.4051719,537.306667 88.3091719,538.768 93.5571719,538.768 Z M93.5571719,531.088 C91.5945052,531.088 90.1225052,530.48 89.1411719,529.264 C88.1598385,528.048 87.6691719,526.309333 87.6691719,524.048 C87.6691719,522.512 87.7971719,520.976 88.0531719,519.44 L88.0531719,519.44 L89.3331719,511.76 C89.9731719,507.877333 90.9438385,504.986667 92.2451719,503.088 C93.5465052,501.189333 95.4771719,500.24 98.0371719,500.24 C99.9998385,500.24 101.471839,500.848 102.453172,502.064 C103.434505,503.28 103.925172,505.018667 103.925172,507.28 C103.925172,508.816 103.797172,510.352 103.541172,511.888 L103.541172,511.888 L102.261172,519.568 C101.621172,523.450667 100.650505,526.341333 99.3491719,528.24 C98.0478385,530.138667 96.1171719,531.088 93.5571719,531.088 Z M126.260586,538 L132.212586,508.368 L132.532586,508.368 L135.668586,516.112 L141.044586,530.64 L151.604586,517.072 L158.388586,508.496 L158.772586,508.496 L152.820586,538 L161.652586,538 L170.612586,493.328 L160.308586,493.328 L144.116586,514.576 L143.860586,514.576 L136.116586,493.328 L126.388586,493.328 L117.428586,538 L126.260586,538 Z M179.252195,538 L183.668195,527.184 L196.212195,527.184 L197.300195,538 L207.028195,538 L202.164195,493.328 L188.980195,493.328 L169.332195,538 L179.252195,538 Z M195.828195,519.504 L186.868195,519.504 L193.908195,502.608 L194.484195,502.608 L195.828195,519.504 Z M221.747609,538 L229.171609,493.328 L219.699609,493.328 L212.275609,538 L221.747609,538 Z M238.834828,538 L243.826828,508.048 L244.466828,508.048 L249.650828,538 L261.042828,538 L268.466828,493.328 L260.210828,493.328 L255.218828,523.28 L254.578828,523.28 L249.394828,493.328 L238.002828,493.328 L230.578828,538 L238.834828,538 Z" id="DOMAIN" fill-opacity="0.85" fill="#000000" fill-rule="nonzero"></path>
<path d="M919.329172,543 C923.894505,543 927.787839,541.88 931.009172,539.64 C934.230505,537.4 936.673172,534.168 938.337172,529.944 C940.001172,525.72 940.833172,520.664 940.833172,514.776 C940.833172,509.485333 939.510505,505.421333 936.865172,502.584 C934.219839,499.746667 930.401172,498.328 925.409172,498.328 L925.409172,498.328 L912.289172,498.328 L904.801172,543 L919.329172,543 Z M919.521172,535.512 L915.489172,535.512 L920.417172,505.816 L924.577172,505.816 C926.838505,505.816 928.523839,506.402667 929.633172,507.576 C930.742505,508.749333 931.297172,510.552 931.297172,512.984 C931.297172,514.349333 931.169172,515.8 930.913172,517.336 L930.913172,517.336 L929.569172,525.4 C929.014505,528.856 927.915839,531.405333 926.273172,533.048 C924.630505,534.690667 922.379839,535.512 919.521172,535.512 L919.521172,535.512 Z M949.152586,543 L953.568586,532.184 L966.112586,532.184 L967.200586,543 L976.928586,543 L972.064586,498.328 L958.880586,498.328 L939.232586,543 L949.152586,543 Z M965.728586,524.504 L956.768586,524.504 L963.808586,507.608 L964.384586,507.608 L965.728586,524.504 Z M1001.184,543 L1007.328,506.136 L1020.256,506.136 L1021.536,498.328 L986.208,498.328 L984.928,506.136 L997.856,506.136 L991.712,543 L1001.184,543 Z M1025.95141,543 L1030.36741,532.184 L1042.91141,532.184 L1043.99941,543 L1053.72741,543 L1048.86341,498.328 L1035.67941,498.328 L1016.03141,543 L1025.95141,543 Z M1042.52741,524.504 L1033.56741,524.504 L1040.60741,507.608 L1041.18341,507.608 L1042.52741,524.504 Z" id="DATA" fill-opacity="0.85" fill="#000000" fill-rule="nonzero"></path>
<path d="M266.501044,316 L266.501044,311.86 L255.557044,311.86 L255.557044,305.344 L266.141044,305.344 L266.141044,301.204 L255.557044,301.204 L255.557044,295.012 L266.501044,295.012 L266.501044,290.872 L250.553044,290.872 L250.553044,316 L266.501044,316 Z M275.788714,316 L275.788714,298.54 L276.184714,298.54 L282.376714,316 L288.496714,316 L288.496714,290.872 L284.212714,290.872 L284.212714,308.296 L283.816714,308.296 L277.624714,290.872 L271.504714,290.872 L271.504714,316 L275.788714,316 Z M304.084385,316 L304.084385,295.012 L311.536385,295.012 L311.536385,290.872 L291.664385,290.872 L291.664385,295.012 L299.116385,295.012 L299.116385,316 L304.084385,316 Z M320.284055,316 L320.284055,290.872 L315.316055,290.872 L315.316055,316 L320.284055,316 Z M336.483615,316 L336.483615,295.012 L343.935615,295.012 L343.935615,290.872 L324.063615,290.872 L324.063615,295.012 L331.515615,295.012 L331.515615,316 L336.483615,316 Z M358.083286,316 L358.083286,306.928 L366.183286,290.872 L360.783286,290.872 L357.975286,296.812 L355.815286,301.888 L355.563286,301.888 L353.439286,296.812 L350.595286,290.872 L345.015286,290.872 L353.115286,306.928 L353.115286,316 L358.083286,316 Z" id="ENTITY" fill="#FFFFFF" fill-rule="nonzero"></path>
<path d="M1094.63677,316 L1094.63677,298.54 L1094.88877,298.54 L1096.83277,302.536 L1101.80077,311.716 L1106.91277,302.5 L1108.78477,298.72 L1109.03677,298.72 L1109.03677,316 L1113.78877,316 L1113.78877,290.872 L1108.17277,290.872 L1101.87277,302.932 L1101.80077,302.932 L1095.46477,290.872 L1089.84877,290.872 L1089.84877,316 L1094.63677,316 Z M1128.80055,316.432 C1132.06455,316.432 1134.48855,315.316 1136.07255,313.084 C1137.65655,310.852 1138.44855,307.636 1138.44855,303.436 C1138.44855,299.236 1137.65655,296.02 1136.07255,293.788 C1134.48855,291.556 1132.06455,290.44 1128.80055,290.44 C1125.53655,290.44 1123.11255,291.556 1121.52855,293.788 C1119.94455,296.02 1119.15255,299.236 1119.15255,303.436 C1119.15255,307.636 1119.94455,310.852 1121.52855,313.084 C1123.11255,315.316 1125.53655,316.432 1128.80055,316.432 Z M1128.80055,312.364 C1127.26455,312.364 1126.16055,311.794 1125.48855,310.654 C1124.81655,309.514 1124.48055,307.828 1124.48055,305.596 L1124.48055,305.596 L1124.48055,301.276 C1124.48055,299.044 1124.81655,297.358 1125.48855,296.218 C1126.16055,295.078 1127.26455,294.508 1128.80055,294.508 C1130.33655,294.508 1131.44055,295.078 1132.11255,296.218 C1132.78455,297.358 1133.12055,299.044 1133.12055,301.276 L1133.12055,301.276 L1133.12055,305.56 C1133.12055,307.792 1132.78455,309.484 1132.11255,310.636 C1131.44055,311.788 1130.33655,312.364 1128.80055,312.364 Z M1150.00422,316 C1153.29222,316 1155.75222,314.932 1157.38422,312.796 C1159.01622,310.66 1159.83222,307.54 1159.83222,303.436 C1159.83222,299.332 1159.01622,296.212 1157.38422,294.076 C1155.75222,291.94 1153.29222,290.872 1150.00422,290.872 L1150.00422,290.872 L1142.08422,290.872 L1142.08422,316 L1150.00422,316 Z M1149.68022,312.04 L1147.01622,312.04 L1147.01622,294.832 L1149.68022,294.832 C1151.33622,294.832 1152.56622,295.378 1153.37022,296.47 C1154.17422,297.562 1154.57622,299.14 1154.57622,301.204 L1154.57622,301.204 L1154.57622,305.632 C1154.57622,307.72 1154.17422,309.31 1153.37022,310.402 C1152.56622,311.494 1151.33622,312.04 1149.68022,312.04 L1149.68022,312.04 Z M1180.09989,316 L1180.09989,311.86 L1169.15589,311.86 L1169.15589,305.344 L1179.73989,305.344 L1179.73989,301.204 L1169.15589,301.204 L1169.15589,295.012 L1180.09989,295.012 L1180.09989,290.872 L1164.15189,290.872 L1164.15189,316 L1180.09989,316 Z M1202.31156,316 L1202.31156,311.86 L1191.29556,311.86 L1191.29556,290.872 L1186.29156,290.872 L1186.29156,316 L1202.31156,316 Z" id="MODEL" fill="#FFFFFF" fill-rule="nonzero"></path>
<path d="M414.400494,524.432 C416.752494,524.432 418.552494,524.048 419.800494,523.28 C421.048494,522.512 421.906494,521.384 422.374494,519.896 C422.842494,518.408 423.076494,516.416 423.076494,513.92 L423.076494,513.92 L423.076494,498.872 L418.072494,498.872 L418.072494,514.64 C418.072494,516.008 417.994494,517.082 417.838494,517.862 C417.682494,518.642 417.346494,519.254 416.830494,519.698 C416.314494,520.142 415.504494,520.364 414.400494,520.364 C413.296494,520.364 412.486494,520.142 411.970494,519.698 C411.454494,519.254 411.118494,518.642 410.962494,517.862 C410.806494,517.082 410.728494,516.008 410.728494,514.64 L410.728494,514.64 L410.728494,498.872 L405.724494,498.872 L405.724494,513.92 C405.724494,516.416 405.958494,518.408 406.426494,519.896 C406.894494,521.384 407.752494,522.512 409.000494,523.28 C410.248494,524.048 412.048494,524.432 414.400494,524.432 Z M435.676165,524.432 C437.668165,524.432 439.378165,524.09 440.806165,523.406 C442.234165,522.722 443.314165,521.774 444.046165,520.562 C444.778165,519.35 445.144165,517.952 445.144165,516.368 C445.144165,514.472 444.598165,512.924 443.506165,511.724 C442.414165,510.524 440.824165,509.732 438.736165,509.348 L438.736165,509.348 L436.072165,508.88 C434.752165,508.664 433.816165,508.31 433.264165,507.818 C432.712165,507.326 432.436165,506.636 432.436165,505.748 C432.436165,504.692 432.766165,503.894 433.426165,503.354 C434.086165,502.814 435.052165,502.544 436.324165,502.544 C437.500165,502.544 438.562165,502.754 439.510165,503.174 C440.458165,503.594 441.268165,504.212 441.940165,505.028 L441.940165,505.028 L444.856165,501.86 C443.944165,500.78 442.762165,499.94 441.310165,499.34 C439.858165,498.74 438.196165,498.44 436.324165,498.44 C433.492165,498.44 431.296165,499.1 429.736165,500.42 C428.176165,501.74 427.396165,503.588 427.396165,505.964 C427.396165,507.86 427.918165,509.432 428.962165,510.68 C430.006165,511.928 431.620165,512.732 433.804165,513.092 L433.804165,513.092 L436.468165,513.524 C437.764165,513.74 438.688165,514.094 439.240165,514.586 C439.792165,515.078 440.068165,515.804 440.068165,516.764 C440.068165,517.916 439.702165,518.798 438.970165,519.41 C438.238165,520.022 437.188165,520.328 435.820165,520.328 C434.620165,520.328 433.474165,520.076 432.382165,519.572 C431.290165,519.068 430.288165,518.3 429.376165,517.268 L429.376165,517.268 L426.388165,520.436 C427.396165,521.708 428.680165,522.692 430.240165,523.388 C431.800165,524.084 433.612165,524.432 435.676165,524.432 Z M465.699835,524 L465.699835,519.86 L454.755835,519.86 L454.755835,513.344 L465.339835,513.344 L465.339835,509.204 L454.755835,509.204 L454.755835,503.012 L465.699835,503.012 L465.699835,498.872 L449.751835,498.872 L449.751835,524 L465.699835,524 Z M404.212659,571.432 C406.636659,571.432 408.550659,570.826 409.954659,569.614 C411.358659,568.402 412.348659,566.692 412.924659,564.484 L412.924659,564.484 L408.280659,563.26 C407.944659,564.604 407.470659,565.624 406.858659,566.32 C406.246659,567.016 405.340659,567.364 404.140659,567.364 C402.628659,567.364 401.524659,566.782 400.828659,565.618 C400.132659,564.454 399.784659,562.78 399.784659,560.596 L399.784659,560.596 L399.784659,556.276 C399.784659,554.092 400.132659,552.418 400.828659,551.254 C401.524659,550.09 402.628659,549.508 404.140659,549.508 C405.340659,549.508 406.246659,549.856 406.858659,550.552 C407.470659,551.248 407.944659,552.268 408.280659,553.612 L408.280659,553.612 L412.924659,552.388 C412.348659,550.18 411.358659,548.47 409.954659,547.258 C408.550659,546.046 406.636659,545.44 404.212659,545.44 C400.948659,545.44 398.506659,546.556 396.886659,548.788 C395.266659,551.02 394.456659,554.236 394.456659,558.436 C394.456659,562.636 395.266659,565.852 396.886659,568.084 C398.506659,570.316 400.948659,571.432 404.212659,571.432 Z M419.80033,571 L421.45633,564.772 L428.65633,564.772 L430.34833,571 L435.67633,571 L428.72833,545.872 L421.70833,545.872 L414.72433,571 L419.80033,571 Z M427.86433,560.704 L422.28433,560.704 L424.94833,550.768 L425.23633,550.768 L427.86433,560.704 Z M446.476,571.432 C448.468,571.432 450.178,571.09 451.606,570.406 C453.034,569.722 454.114,568.774 454.846,567.562 C455.578,566.35 455.944,564.952 455.944,563.368 C455.944,561.472 455.398,559.924 454.306,558.724 C453.214,557.524 451.624,556.732 449.536,556.348 L449.536,556.348 L446.872,555.88 C445.552,555.664 444.616,555.31 444.064,554.818 C443.512,554.326 443.236,553.636 443.236,552.748 C443.236,551.692 443.566,550.894 444.226,550.354 C444.886,549.814 445.852,549.544 447.124,549.544 C448.3,549.544 449.362,549.754 450.31,550.174 C451.258,550.594 452.068,551.212 452.74,552.028 L452.74,552.028 L455.656,548.86 C454.744,547.78 453.562,546.94 452.11,546.34 C450.658,545.74 448.996,545.44 447.124,545.44 C444.292,545.44 442.096,546.1 440.536,547.42 C438.976,548.74 438.196,550.588 438.196,552.964 C438.196,554.86 438.718,556.432 439.762,557.68 C440.806,558.928 442.42,559.732 444.604,560.092 L444.604,560.092 L447.268,560.524 C448.564,560.74 449.488,561.094 450.04,561.586 C450.592,562.078 450.868,562.804 450.868,563.764 C450.868,564.916 450.502,565.798 449.77,566.41 C449.038,567.022 447.988,567.328 446.62,567.328 C445.42,567.328 444.274,567.076 443.182,566.572 C442.09,566.068 441.088,565.3 440.176,564.268 L440.176,564.268 L437.188,567.436 C438.196,568.708 439.48,569.692 441.04,570.388 C442.6,571.084 444.412,571.432 446.476,571.432 Z M476.49967,571 L476.49967,566.86 L465.55567,566.86 L465.55567,560.344 L476.13967,560.344 L476.13967,556.204 L465.55567,556.204 L465.55567,550.012 L476.49967,550.012 L476.49967,545.872 L460.55167,545.872 L460.55167,571 L476.49967,571 Z" id="USECASE" fill="#FFFFFF" fill-rule="nonzero"></path>
<path d="M1227.77682,524 L1227.77682,514.424 L1230.51282,514.424 L1235.04882,524 L1240.52082,524 L1235.33682,513.812 C1236.82482,513.452 1237.98282,512.636 1238.81082,511.364 C1239.63882,510.092 1240.05282,508.544 1240.05282,506.72 C1240.05282,504.296 1239.39282,502.382 1238.07282,500.978 C1236.75282,499.574 1234.88082,498.872 1232.45682,498.872 L1232.45682,498.872 L1222.80882,498.872 L1222.80882,524 L1227.77682,524 Z M1231.34082,510.536 L1227.77682,510.536 L1227.77682,502.94 L1231.34082,502.94 C1232.61282,502.94 1233.51282,503.192 1234.04082,503.696 C1234.56882,504.2 1234.83282,505.016 1234.83282,506.144 L1234.83282,506.144 L1234.83282,507.332 C1234.83282,508.46 1234.56882,509.276 1234.04082,509.78 C1233.51282,510.284 1232.61282,510.536 1231.34082,510.536 L1231.34082,510.536 Z M1260.50049,524 L1260.50049,519.86 L1249.55649,519.86 L1249.55649,513.344 L1260.14049,513.344 L1260.14049,509.204 L1249.55649,509.204 L1249.55649,503.012 L1260.50049,503.012 L1260.50049,498.872 L1244.55249,498.872 L1244.55249,524 L1260.50049,524 Z M1271.04816,524 L1271.04816,514.604 L1275.65616,514.604 C1278.08016,514.604 1279.95216,513.902 1281.27216,512.498 C1282.59216,511.094 1283.25216,509.168 1283.25216,506.72 C1283.25216,504.296 1282.59216,502.382 1281.27216,500.978 C1279.95216,499.574 1278.08016,498.872 1275.65616,498.872 L1275.65616,498.872 L1266.00816,498.872 L1266.00816,524 L1271.04816,524 Z M1274.50416,510.536 L1271.04816,510.536 L1271.04816,502.94 L1274.50416,502.94 C1275.75216,502.94 1276.64616,503.192 1277.18616,503.696 C1277.72616,504.2 1277.99616,505.016 1277.99616,506.144 L1277.99616,506.144 L1277.99616,507.332 C1277.99616,508.46 1277.72616,509.276 1277.18616,509.78 C1276.64616,510.284 1275.75216,510.536 1274.50416,510.536 L1274.50416,510.536 Z M1295.59984,524.432 C1298.86384,524.432 1301.28784,523.316 1302.87184,521.084 C1304.45584,518.852 1305.24784,515.636 1305.24784,511.436 C1305.24784,507.236 1304.45584,504.02 1302.87184,501.788 C1301.28784,499.556 1298.86384,498.44 1295.59984,498.44 C1292.33584,498.44 1289.91184,499.556 1288.32784,501.788 C1286.74384,504.02 1285.95184,507.236 1285.95184,511.436 C1285.95184,515.636 1286.74384,518.852 1288.32784,521.084 C1289.91184,523.316 1292.33584,524.432 1295.59984,524.432 Z M1295.59984,520.364 C1294.06384,520.364 1292.95984,519.794 1292.28784,518.654 C1291.61584,517.514 1291.27984,515.828 1291.27984,513.596 L1291.27984,513.596 L1291.27984,509.276 C1291.27984,507.044 1291.61584,505.358 1292.28784,504.218 C1292.95984,503.078 1294.06384,502.508 1295.59984,502.508 C1297.13584,502.508 1298.23984,503.078 1298.91184,504.218 C1299.58384,505.358 1299.91984,507.044 1299.91984,509.276 L1299.91984,509.276 L1299.91984,513.56 C1299.91984,515.792 1299.58384,517.484 1298.91184,518.636 C1298.23984,519.788 1297.13584,520.364 1295.59984,520.364 Z M1322.85151,515.396 L1322.85151,510.644 L1311.54751,510.644 L1311.54751,515.396 L1322.85151,515.396 Z M1225.07704,571.432 C1227.06904,571.432 1228.77904,571.09 1230.20704,570.406 C1231.63504,569.722 1232.71504,568.774 1233.44704,567.562 C1234.17904,566.35 1234.54504,564.952 1234.54504,563.368 C1234.54504,561.472 1233.99904,559.924 1232.90704,558.724 C1231.81504,557.524 1230.22504,556.732 1228.13704,556.348 L1228.13704,556.348 L1225.47304,555.88 C1224.15304,555.664 1223.21704,555.31 1222.66504,554.818 C1222.11304,554.326 1221.83704,553.636 1221.83704,552.748 C1221.83704,551.692 1222.16704,550.894 1222.82704,550.354 C1223.48704,549.814 1224.45304,549.544 1225.72504,549.544 C1226.90104,549.544 1227.96304,549.754 1228.91104,550.174 C1229.85904,550.594 1230.66904,551.212 1231.34104,552.028 L1231.34104,552.028 L1234.25704,548.86 C1233.34504,547.78 1232.16304,546.94 1230.71104,546.34 C1229.25904,545.74 1227.59704,545.44 1225.72504,545.44 C1222.89304,545.44 1220.69704,546.1 1219.13704,547.42 C1217.57704,548.74 1216.79704,550.588 1216.79704,552.964 C1216.79704,554.86 1217.31904,556.432 1218.36304,557.68 C1219.40704,558.928 1221.02104,559.732 1223.20504,560.092 L1223.20504,560.092 L1225.86904,560.524 C1227.16504,560.74 1228.08904,561.094 1228.64104,561.586 C1229.19304,562.078 1229.46904,562.804 1229.46904,563.764 C1229.46904,564.916 1229.10304,565.798 1228.37104,566.41 C1227.63904,567.022 1226.58904,567.328 1225.22104,567.328 C1224.02104,567.328 1222.87504,567.076 1221.78304,566.572 C1220.69104,566.068 1219.68904,565.3 1218.77704,564.268 L1218.77704,564.268 L1215.78904,567.436 C1216.79704,568.708 1218.08104,569.692 1219.64104,570.388 C1221.20104,571.084 1223.01304,571.432 1225.07704,571.432 Z M1244.08471,571 L1244.08471,545.872 L1239.11671,545.872 L1239.11671,571 L1244.08471,571 Z M1260.28427,571 L1260.28427,550.012 L1267.73627,550.012 L1267.73627,545.872 L1247.86427,545.872 L1247.86427,550.012 L1255.31627,550.012 L1255.31627,571 L1260.28427,571 Z M1279.39995,571.432 C1282.66395,571.432 1285.08795,570.316 1286.67195,568.084 C1288.25595,565.852 1289.04795,562.636 1289.04795,558.436 C1289.04795,554.236 1288.25595,551.02 1286.67195,548.788 C1285.08795,546.556 1282.66395,545.44 1279.39995,545.44 C1276.13595,545.44 1273.71195,546.556 1272.12795,548.788 C1270.54395,551.02 1269.75195,554.236 1269.75195,558.436 C1269.75195,562.636 1270.54395,565.852 1272.12795,568.084 C1273.71195,570.316 1276.13595,571.432 1279.39995,571.432 Z M1279.39995,567.364 C1277.86395,567.364 1276.75995,566.794 1276.08795,565.654 C1275.41595,564.514 1275.07995,562.828 1275.07995,560.596 L1275.07995,560.596 L1275.07995,556.276 C1275.07995,554.044 1275.41595,552.358 1276.08795,551.218 C1276.75995,550.078 1277.86395,549.508 1279.39995,549.508 C1280.93595,549.508 1282.03995,550.078 1282.71195,551.218 C1283.38395,552.358 1283.71995,554.044 1283.71995,556.276 L1283.71995,556.276 L1283.71995,560.56 C1283.71995,562.792 1283.38395,564.484 1282.71195,565.636 C1282.03995,566.788 1280.93595,567.364 1279.39995,567.364 Z M1297.97562,571 L1297.97562,561.424 L1300.71162,561.424 L1305.24762,571 L1310.71962,571 L1305.53562,560.812 C1307.02362,560.452 1308.18162,559.636 1309.00962,558.364 C1309.83762,557.092 1310.25162,555.544 1310.25162,553.72 C1310.25162,551.296 1309.59162,549.382 1308.27162,547.978 C1306.95162,546.574 1305.07962,545.872 1302.65562,545.872 L1302.65562,545.872 L1293.00762,545.872 L1293.00762,571 L1297.97562,571 Z M1301.53962,557.536 L1297.97562,557.536 L1297.97562,549.94 L1301.53962,549.94 C1302.81162,549.94 1303.71162,550.192 1304.23962,550.696 C1304.76762,551.2 1305.03162,552.016 1305.03162,553.144 L1305.03162,553.144 L1305.03162,554.332 C1305.03162,555.46 1304.76762,556.276 1304.23962,556.78 C1303.71162,557.284 1302.81162,557.536 1301.53962,557.536 L1301.53962,557.536 Z M1325.08329,571 L1325.08329,561.928 L1333.18329,545.872 L1327.78329,545.872 L1324.97529,551.812 L1322.81529,556.888 L1322.56329,556.888 L1320.43929,551.812 L1317.59529,545.872 L1312.01529,545.872 L1320.11529,561.928 L1320.11529,571 L1325.08329,571 Z" id="REPO-SITORY" fill="#FFFFFF" fill-rule="nonzero"></path>
<path d="M2134,4.88675135 L2566.67777,254.693376 L2566.67777,754.306624 L2134,1004.11325 L1701.32223,754.306624 L1701.32223,254.693376 L2134,4.88675135 Z" id="Polygon-Copy-3" stroke="#55D4F5" stroke-width="5"></path>
<g id="arrow-from-left-duotone" transform="translate(602.000000, 416.000000)" fill="#55D4F5" fill-rule="nonzero">
<path d="M0,90.9374833 L0,6.06251668 C-0.00397742587,4.45340787 0.626878736,2.90904065 1.75296181,1.77122531 C2.87904488,0.633409968 4.40748778,-0.00401886529 6,0 L10,0 C11.5925122,-0.00401886529 13.1209551,0.633409968 14.2470382,1.77122531 C15.3731213,2.90904065 16.0039774,4.45340787 16,6.06251668 L16,90.9374833 C16.0039774,92.5465921 15.3731213,94.0909594 14.2470382,95.2287747 C13.1209551,96.36659 11.5925122,97.0040189 10,97 L6,97 C4.40748778,97.0040189 2.87904488,96.36659 1.75296181,95.2287747 C0.626878736,94.0909594 -0.00397742587,92.5465921 0,90.9374833 Z" id="Path" opacity="0.4"></path>
<path d="M154.073647,15.1083961 L158.371221,10.7901451 C159.504069,9.64454829 161.04733,9 162.65742,9 C164.26751,9 165.810772,9.64454829 166.943619,10.7901451 L201.215514,45.1969363 C202.357887,46.3368039 203,47.8851778 203,49.5 C203,51.1148222 202.357887,52.6631961 201.215514,53.8030637 L166.943619,88.2098549 C165.810772,89.3554517 164.26751,90 162.65742,90 C161.04733,90 159.504069,89.3554517 158.371221,88.2098549 L154.073647,83.8916039 C152.931273,82.7517362 152.289161,81.2033624 152.289161,79.5885402 C152.289161,77.9737179 152.931273,76.4253441 154.073647,75.2854765 L170.659757,58.6275575 L30.0671902,58.6275575 C28.4554467,58.6275625 26.9099366,57.9854445 25.7716856,56.8428904 C24.6334345,55.7003363 23.9959965,54.1512537 24,52.5374567 L24,46.4397623 C23.9953236,44.8255274 24.6324645,43.2757935 25.7707886,42.1326912 C26.9091127,40.9895889 28.4550075,40.3471235 30.0671902,40.3471304 L170.659757,40.3471304 L154.073647,23.6816178 C152.935128,22.5463819 152.295116,21.0038258 152.295116,19.3950069 C152.295116,17.786188 152.935128,16.243632 154.073647,15.1083961 Z" id="Path"></path>
</g>
<g id="Group" transform="translate(2048.000000, 92.000000)">
<polygon id="Polygon-Copy-5" fill="#55D4F5" points="80 0 136.291651 32.25 136.291651 96.75 80 129 23.7083488 96.75 23.7083488 32.25"></polygon>
<polygon id="Polygon-Copy-5" fill="#55D4F5" points="144.5 104 207.286842 140 207.286842 212 144.5 248 81.7131582 212 81.7131582 140"></polygon>
<path d="M60.1504578,69 L64.7754578,51.55 L60.8004578,51.55 L58.7254578,60.425 L57.6754578,65.45 L57.4754578,65.45 L56.4504578,60.425 L54.4004578,51.55 L50.2254578,51.55 L54.8504578,69 L60.1504578,69 Z M70.6252289,69 L70.6252289,51.55 L66.8752289,51.55 L66.8752289,69 L70.6252289,69 Z M85.6499237,69 L85.6499237,65.925 L78.2499237,65.925 L78.2499237,61.7 L85.3999237,61.7 L85.3999237,58.625 L78.2499237,58.625 L78.2499237,54.625 L85.6499237,54.625 L85.6499237,51.55 L74.4999237,51.55 L74.4999237,69 L85.6499237,69 Z M95.6246948,69 L97.8246948,59.55 L98.6996948,55.725 L98.7746948,55.725 L99.6246948,59.55 L101.824695,69 L106.149695,69 L110.199695,51.55 L106.599695,51.55 L104.924695,59.925 L103.999695,64.775 L103.924695,64.775 L102.849695,59.925 L100.899695,51.55 L96.7496948,51.55 L94.8246948,59.925 L93.7246948,64.775 L93.6496948,64.775 L92.7246948,59.925 L91.0746948,51.55 L87.2996948,51.55 L91.2746948,69 L95.6246948,69 Z" id="VIEW" fill="#FFFFFF" fill-rule="nonzero"></path>
<path d="M121.650572,166 L126.275572,148.55 L122.300572,148.55 L120.225572,157.425 L119.175572,162.45 L118.975572,162.45 L117.950572,157.425 L115.900572,148.55 L111.725572,148.55 L116.350572,166 L121.650572,166 Z M132.125343,166 L132.125343,148.55 L128.375343,148.55 L128.375343,166 L132.125343,166 Z M147.150038,166 L147.150038,162.925 L139.750038,162.925 L139.750038,158.7 L146.900038,158.7 L146.900038,155.625 L139.750038,155.625 L139.750038,151.625 L147.150038,151.625 L147.150038,148.55 L136.000038,148.55 L136.000038,166 L147.150038,166 Z M157.124809,166 L159.324809,156.55 L160.199809,152.725 L160.274809,152.725 L161.124809,156.55 L163.324809,166 L167.649809,166 L171.699809,148.55 L168.099809,148.55 L166.424809,156.925 L165.499809,161.775 L165.424809,161.775 L164.349809,156.925 L162.399809,148.55 L158.249809,148.55 L156.324809,156.925 L155.224809,161.775 L155.149809,161.775 L154.224809,156.925 L152.574809,148.55 L148.799809,148.55 L152.774809,166 L157.124809,166 Z M182.999657,160.15 L182.999657,156.6 L174.999657,156.6 L174.999657,160.15 L182.999657,160.15 Z M114.275534,199 L114.275534,187.375 L114.350534,187.375 L115.675534,190.125 L119.000534,196.275 L122.400534,190.1 L123.675534,187.55 L123.750534,187.55 L123.750534,199 L127.325534,199 L127.325534,181.55 L123.275534,181.55 L119.050534,189.725 L119.000534,189.725 L114.725534,181.55 L110.700534,181.55 L110.700534,199 L114.275534,199 Z M137.750381,199.3 C140.050381,199.3 141.762881,198.525 142.887881,196.975 C144.012881,195.425 144.575381,193.191667 144.575381,190.275 C144.575381,187.358333 144.012881,185.125 142.887881,183.575 C141.762881,182.025 140.050381,181.25 137.750381,181.25 C135.450381,181.25 133.737881,182.025 132.612881,183.575 C131.487881,185.125 130.925381,187.358333 130.925381,190.275 C130.925381,193.191667 131.487881,195.425 132.612881,196.975 C133.737881,198.525 135.450381,199.3 137.750381,199.3 Z M137.750381,196.275 C136.733715,196.275 136.008715,195.9 135.575381,195.15 C135.142048,194.4 134.925381,193.283333 134.925381,191.8 L134.925381,191.8 L134.925381,188.75 C134.925381,187.266667 135.142048,186.15 135.575381,185.4 C136.008715,184.65 136.733715,184.275 137.750381,184.275 C138.767048,184.275 139.492048,184.65 139.925381,185.4 C140.358715,186.15 140.575381,187.266667 140.575381,188.75 L140.575381,188.75 L140.575381,191.775 C140.575381,193.258333 140.358715,194.379167 139.925381,195.1375 C139.492048,195.895833 138.767048,196.275 137.750381,196.275 Z M152.475153,199 C154.791819,199 156.525153,198.254167 157.675153,196.7625 C158.825153,195.270833 159.400153,193.108333 159.400153,190.275 C159.400153,187.441667 158.825153,185.279167 157.675153,183.7875 C156.525153,182.295833 154.791819,181.55 152.475153,181.55 L152.475153,181.55 L146.850153,181.55 L146.850153,199 L152.475153,199 Z M152.225153,196.05 L150.550153,196.05 L150.550153,184.5 L152.225153,184.5 C153.325153,184.5 154.137653,184.854167 154.662653,185.5625 C155.187653,186.270833 155.450153,187.308333 155.450153,188.675 L155.450153,188.675 L155.450153,191.85 C155.450153,193.233333 155.187653,194.279167 154.662653,194.9875 C154.137653,195.695833 153.325153,196.05 152.225153,196.05 L152.225153,196.05 Z M173.399924,199 L173.399924,195.925 L165.999924,195.925 L165.999924,191.7 L173.149924,191.7 L173.149924,188.625 L165.999924,188.625 L165.999924,184.625 L173.399924,184.625 L173.399924,181.55 L162.249924,181.55 L162.249924,199 L173.399924,199 Z M188.824695,199 L188.824695,195.925 L181.324695,195.925 L181.324695,181.55 L177.549695,181.55 L177.549695,199 L188.824695,199 Z" id="VIEW-MODEL" fill="#FFFFFF" fill-rule="nonzero"></path>
</g>
<path d="M1799.95288,572 L1804.36888,561.184 L1816.91288,561.184 L1818.00088,572 L1827.72888,572 L1822.86488,527.328 L1809.68088,527.328 L1790.03288,572 L1799.95288,572 Z M1816.52888,553.504 L1807.56888,553.504 L1814.60888,536.608 L1815.18488,536.608 L1816.52888,553.504 Z M1842.64029,572 L1845.39229,555.616 L1853.00829,555.616 C1856.20829,555.616 1859.01363,554.954667 1861.42429,553.632 C1863.83496,552.309333 1865.69096,550.410667 1866.99229,547.936 C1868.29363,545.461333 1868.94429,542.538667 1868.94429,539.168 C1868.94429,535.626667 1867.88829,532.768 1865.77629,530.592 C1863.66429,528.416 1860.66696,527.328 1856.78429,527.328 L1856.78429,527.328 L1840.65629,527.328 L1833.16829,572 L1842.64029,572 Z M1851.66429,547.936 L1846.67229,547.936 L1848.84829,534.944 L1853.84029,534.944 C1855.71763,534.944 1857.06163,535.253333 1857.87229,535.872 C1858.68296,536.490667 1859.08829,537.525333 1859.08829,538.976 C1859.08829,539.616 1859.04563,540.192 1858.96029,540.704 L1858.96029,540.704 L1858.64029,542.624 C1858.34163,544.544 1857.64829,545.909333 1856.56029,546.72 C1855.47229,547.530667 1853.84029,547.936 1851.66429,547.936 L1851.66429,547.936 Z M1881.03971,572 L1883.79171,555.616 L1891.40771,555.616 C1894.60771,555.616 1897.41304,554.954667 1899.82371,553.632 C1902.23437,552.309333 1904.09037,550.410667 1905.39171,547.936 C1906.69304,545.461333 1907.34371,542.538667 1907.34371,539.168 C1907.34371,535.626667 1906.28771,532.768 1904.17571,530.592 C1902.06371,528.416 1899.06637,527.328 1895.18371,527.328 L1895.18371,527.328 L1879.05571,527.328 L1871.56771,572 L1881.03971,572 Z M1890.06371,547.936 L1885.07171,547.936 L1887.24771,534.944 L1892.23971,534.944 C1894.11704,534.944 1895.46104,535.253333 1896.27171,535.872 C1897.08237,536.490667 1897.48771,537.525333 1897.48771,538.976 C1897.48771,539.616 1897.44504,540.192 1897.35971,540.704 L1897.35971,540.704 L1897.03971,542.624 C1896.74104,544.544 1896.04771,545.909333 1894.95971,546.72 C1893.87171,547.530667 1892.23971,547.936 1890.06371,547.936 L1890.06371,547.936 Z" id="APP" fill-opacity="0.85" fill="#000000" fill-rule="nonzero"></path>
<path d="M2008.66062,259.288 C2010.24462,259.288 2011.54462,258.888 2012.56062,258.088 C2013.57662,257.288 2014.42862,256.08 2015.11662,254.464 L2015.11662,254.464 L2012.06862,253.552 C2011.71662,254.432 2011.28062,255.128 2010.76062,255.64 C2010.24062,256.152 2009.62062,256.408 2008.90062,256.408 C2008.05262,256.408 2007.43662,256.176 2007.05262,255.712 C2006.66862,255.248 2006.47662,254.576 2006.47662,253.696 C2006.47662,253.392 2006.49662,253.088 2006.53662,252.784 C2006.57662,252.48 2006.61262,252.192 2006.64462,251.92 C2006.66062,251.904 2006.66862,251.888 2006.66862,251.872 L2006.66862,251.872 L2006.66862,251.824 L2007.10062,249.208 C2007.34062,247.8 2007.73262,246.72 2008.27662,245.968 C2008.82062,245.216 2009.56462,244.84 2010.50862,244.84 C2011.30862,244.84 2011.87262,245.072 2012.20062,245.536 C2012.52862,246 2012.71662,246.68 2012.76462,247.576 L2012.76462,247.576 L2016.19662,246.88 C2016.10062,245.36 2015.60062,244.16 2014.69662,243.28 C2013.79262,242.4 2012.44462,241.96 2010.65262,241.96 C2009.10062,241.96 2007.73662,242.42 2006.56062,243.34 C2005.38462,244.26 2004.48062,245.544 2003.84862,247.192 C2003.21662,248.84 2002.90062,250.744 2002.90062,252.904 C2002.90062,254.952 2003.37662,256.528 2004.32862,257.632 C2005.28062,258.736 2006.72462,259.288 2008.66062,259.288 Z M2022.7964,259.288 C2024.4924,259.288 2025.9044,258.784 2027.0324,257.776 C2028.1604,256.768 2028.9884,255.432 2029.5164,253.768 C2030.0444,252.104 2030.3084,250.272 2030.3084,248.272 C2030.3084,246.256 2029.8284,244.7 2028.8684,243.604 C2027.9084,242.508 2026.4444,241.96 2024.4764,241.96 C2022.7804,241.96 2021.3684,242.464 2020.2404,243.472 C2019.1124,244.48 2018.2844,245.816 2017.7564,247.48 C2017.2284,249.144 2016.9644,250.976 2016.9644,252.976 C2016.9644,254.992 2017.4444,256.548 2018.4044,257.644 C2019.3644,258.74 2020.8284,259.288 2022.7964,259.288 Z M2022.7964,256.408 C2022.0604,256.408 2021.5084,256.18 2021.1404,255.724 C2020.7724,255.268 2020.5884,254.616 2020.5884,253.768 C2020.5884,253.192 2020.6364,252.616 2020.7324,252.04 L2020.7324,252.04 L2021.2124,249.16 C2021.4524,247.704 2021.8164,246.62 2022.3044,245.908 C2022.7924,245.196 2023.5164,244.84 2024.4764,244.84 C2025.2124,244.84 2025.7644,245.068 2026.1324,245.524 C2026.5004,245.98 2026.6844,246.632 2026.6844,247.48 C2026.6844,248.056 2026.6364,248.632 2026.5404,249.208 L2026.5404,249.208 L2026.0604,252.088 C2025.8204,253.544 2025.4564,254.628 2024.9684,255.34 C2024.4804,256.052 2023.7564,256.408 2022.7964,256.408 Z M2035.06018,259 L2037.29218,247.888 L2037.41218,247.888 L2038.58818,250.792 L2040.60418,256.24 L2044.56418,251.152 L2047.10818,247.936 L2047.25218,247.936 L2045.02018,259 L2048.33218,259 L2051.69218,242.248 L2047.82818,242.248 L2041.75618,250.216 L2041.66018,250.216 L2038.75618,242.248 L2035.10818,242.248 L2031.74818,259 L2035.06018,259 Z M2056.54004,259 L2057.57204,252.856 L2060.42804,252.856 C2061.62804,252.856 2062.68004,252.608 2063.58404,252.112 C2064.48804,251.616 2065.18404,250.904 2065.67204,249.976 C2066.16004,249.048 2066.40404,247.952 2066.40404,246.688 C2066.40404,245.36 2066.00804,244.288 2065.21604,243.472 C2064.42404,242.656 2063.30004,242.248 2061.84404,242.248 L2061.84404,242.248 L2055.79604,242.248 L2052.98804,259 L2056.54004,259 Z M2059.92404,249.976 L2058.05204,249.976 L2058.86804,245.104 L2060.74004,245.104 C2061.44404,245.104 2061.94804,245.22 2062.25204,245.452 C2062.55604,245.684 2062.70804,246.072 2062.70804,246.616 C2062.70804,246.856 2062.69204,247.072 2062.66004,247.264 L2062.66004,247.264 L2062.54004,247.984 C2062.42804,248.704 2062.16804,249.216 2061.76004,249.52 C2061.35204,249.824 2060.74004,249.976 2059.92404,249.976 L2059.92404,249.976 Z M2073.19582,259.288 C2074.89182,259.288 2076.30382,258.784 2077.43182,257.776 C2078.55982,256.768 2079.38782,255.432 2079.91582,253.768 C2080.44382,252.104 2080.70782,250.272 2080.70782,248.272 C2080.70782,246.256 2080.22782,244.7 2079.26782,243.604 C2078.30782,242.508 2076.84382,241.96 2074.87582,241.96 C2073.17982,241.96 2071.76782,242.464 2070.63982,243.472 C2069.51182,244.48 2068.68382,245.816 2068.15582,247.48 C2067.62782,249.144 2067.36382,250.976 2067.36382,252.976 C2067.36382,254.992 2067.84382,256.548 2068.80382,257.644 C2069.76382,258.74 2071.22782,259.288 2073.19582,259.288 Z M2073.19582,256.408 C2072.45982,256.408 2071.90782,256.18 2071.53982,255.724 C2071.17182,255.268 2070.98782,254.616 2070.98782,253.768 C2070.98782,253.192 2071.03582,252.616 2071.13182,252.04 L2071.13182,252.04 L2071.61182,249.16 C2071.85182,247.704 2072.21582,246.62 2072.70382,245.908 C2073.19182,245.196 2073.91582,244.84 2074.87582,244.84 C2075.61182,244.84 2076.16382,245.068 2076.53182,245.524 C2076.89982,245.98 2077.08382,246.632 2077.08382,247.48 C2077.08382,248.056 2077.03582,248.632 2076.93982,249.208 L2076.93982,249.208 L2076.45982,252.088 C2076.21982,253.544 2075.85582,254.628 2075.36782,255.34 C2074.87982,256.052 2074.15582,256.408 2073.19582,256.408 Z M2091.8436,253.36 L2092.3956,250 L2084.7876,250 L2084.2356,253.36 L2091.8436,253.36 Z M2023.27644,291 L2025.14844,279.768 L2025.38844,279.768 L2027.33244,291 L2031.60444,291 L2034.38844,274.248 L2031.29244,274.248 L2029.42044,285.48 L2029.18044,285.48 L2027.23644,274.248 L2022.96444,274.248 L2020.18044,291 L2023.27644,291 Z M2045.71622,291 L2046.19622,288.072 L2039.02022,288.072 L2039.69222,283.992 L2046.58022,283.992 L2047.06022,281.064 L2040.19622,281.064 L2040.84422,277.176 L2048.04422,277.176 L2048.52422,274.248 L2037.82022,274.248 L2035.01222,291 L2045.71622,291 Z M2052.076,291 L2053.948,279.768 L2054.188,279.768 L2056.132,291 L2060.404,291 L2063.188,274.248 L2060.092,274.248 L2058.22,285.48 L2057.98,285.48 L2056.036,274.248 L2051.764,274.248 L2048.98,291 L2052.076,291 Z M2070.84378,291 L2073.14778,277.176 L2077.99578,277.176 L2078.47578,274.248 L2065.22778,274.248 L2064.74778,277.176 L2069.59578,277.176 L2067.29178,291 L2070.84378,291 Z" id="COMPO-NENT" fill-opacity="0.85" fill="#000000" fill-rule="nonzero"></path>
<path d="M2306,341.732051 L2519.2743,464.866025 L2519.2743,711.133975 L2306,834.267949 L2092.7257,711.133975 L2092.7257,464.866025 L2306,341.732051 Z" id="Polygon-Copy-3" stroke="#55D4F5" stroke-width="3"></path>
<polygon id="Polygon-Copy-5" fill="#55D4F5" points="2309.5 377 2413.85606 436.75 2413.85606 556.25 2309.5 616 2205.14394 556.25 2205.14394 436.75"></polygon>
<polygon id="Polygon-Copy-5" fill="#55D4F5" points="2409.5 591 2472.28684 627 2472.28684 699 2409.5 735 2346.71316 699 2346.71316 627"></polygon>
<path d="M2256.15046,556 L2260.77546,538.55 L2256.80046,538.55 L2254.72546,547.425 L2253.67546,552.45 L2253.47546,552.45 L2252.45046,547.425 L2250.40046,538.55 L2246.22546,538.55 L2250.85046,556 L2256.15046,556 Z M2266.62523,556 L2266.62523,538.55 L2262.87523,538.55 L2262.87523,556 L2266.62523,556 Z M2281.64992,556 L2281.64992,552.925 L2274.24992,552.925 L2274.24992,548.7 L2281.39992,548.7 L2281.39992,545.625 L2274.24992,545.625 L2274.24992,541.625 L2281.64992,541.625 L2281.64992,538.55 L2270.49992,538.55 L2270.49992,556 L2281.64992,556 Z M2291.62469,556 L2293.82469,546.55 L2294.69969,542.725 L2294.77469,542.725 L2295.62469,546.55 L2297.82469,556 L2302.14969,556 L2306.19969,538.55 L2302.59969,538.55 L2300.92469,546.925 L2299.99969,551.775 L2299.92469,551.775 L2298.84969,546.925 L2296.89969,538.55 L2292.74969,538.55 L2290.82469,546.925 L2289.72469,551.775 L2289.64969,551.775 L2288.72469,546.925 L2287.07469,538.55 L2283.29969,538.55 L2287.27469,556 L2291.62469,556 Z" id="VIEW" fill="#FFFFFF" fill-rule="nonzero"></path>
<path d="M2386.65057,653 L2391.27557,635.55 L2387.30057,635.55 L2385.22557,644.425 L2384.17557,649.45 L2383.97557,649.45 L2382.95057,644.425 L2380.90057,635.55 L2376.72557,635.55 L2381.35057,653 L2386.65057,653 Z M2397.12534,653 L2397.12534,635.55 L2393.37534,635.55 L2393.37534,653 L2397.12534,653 Z M2412.15004,653 L2412.15004,649.925 L2404.75004,649.925 L2404.75004,645.7 L2411.90004,645.7 L2411.90004,642.625 L2404.75004,642.625 L2404.75004,638.625 L2412.15004,638.625 L2412.15004,635.55 L2401.00004,635.55 L2401.00004,653 L2412.15004,653 Z M2422.12481,653 L2424.32481,643.55 L2425.19981,639.725 L2425.27481,639.725 L2426.12481,643.55 L2428.32481,653 L2432.64981,653 L2436.69981,635.55 L2433.09981,635.55 L2431.42481,643.925 L2430.49981,648.775 L2430.42481,648.775 L2429.34981,643.925 L2427.39981,635.55 L2423.24981,635.55 L2421.32481,643.925 L2420.22481,648.775 L2420.14981,648.775 L2419.22481,643.925 L2417.57481,635.55 L2413.79981,635.55 L2417.77481,653 L2422.12481,653 Z M2447.99966,647.15 L2447.99966,643.6 L2439.99966,643.6 L2439.99966,647.15 L2447.99966,647.15 Z M2379.27553,686 L2379.27553,674.375 L2379.35053,674.375 L2380.67553,677.125 L2384.00053,683.275 L2387.40053,677.1 L2388.67553,674.55 L2388.75053,674.55 L2388.75053,686 L2392.32553,686 L2392.32553,668.55 L2388.27553,668.55 L2384.05053,676.725 L2384.00053,676.725 L2379.72553,668.55 L2375.70053,668.55 L2375.70053,686 L2379.27553,686 Z M2402.75038,686.3 C2405.05038,686.3 2406.76288,685.525 2407.88788,683.975 C2409.01288,682.425 2409.57538,680.191667 2409.57538,677.275 C2409.57538,674.358333 2409.01288,672.125 2407.88788,670.575 C2406.76288,669.025 2405.05038,668.25 2402.75038,668.25 C2400.45038,668.25 2398.73788,669.025 2397.61288,670.575 C2396.48788,672.125 2395.92538,674.358333 2395.92538,677.275 C2395.92538,680.191667 2396.48788,682.425 2397.61288,683.975 C2398.73788,685.525 2400.45038,686.3 2402.75038,686.3 Z M2402.75038,683.275 C2401.73371,683.275 2401.00871,682.9 2400.57538,682.15 C2400.14205,681.4 2399.92538,680.283333 2399.92538,678.8 L2399.92538,678.8 L2399.92538,675.75 C2399.92538,674.266667 2400.14205,673.15 2400.57538,672.4 C2401.00871,671.65 2401.73371,671.275 2402.75038,671.275 C2403.76705,671.275 2404.49205,671.65 2404.92538,672.4 C2405.35871,673.15 2405.57538,674.266667 2405.57538,675.75 L2405.57538,675.75 L2405.57538,678.775 C2405.57538,680.258333 2405.35871,681.379167 2404.92538,682.1375 C2404.49205,682.895833 2403.76705,683.275 2402.75038,683.275 Z M2417.47515,686 C2419.79182,686 2421.52515,685.254167 2422.67515,683.7625 C2423.82515,682.270833 2424.40015,680.108333 2424.40015,677.275 C2424.40015,674.441667 2423.82515,672.279167 2422.67515,670.7875 C2421.52515,669.295833 2419.79182,668.55 2417.47515,668.55 L2417.47515,668.55 L2411.85015,668.55 L2411.85015,686 L2417.47515,686 Z M2417.22515,683.05 L2415.55015,683.05 L2415.55015,671.5 L2417.22515,671.5 C2418.32515,671.5 2419.13765,671.854167 2419.66265,672.5625 C2420.18765,673.270833 2420.45015,674.308333 2420.45015,675.675 L2420.45015,675.675 L2420.45015,678.85 C2420.45015,680.233333 2420.18765,681.279167 2419.66265,681.9875 C2419.13765,682.695833 2418.32515,683.05 2417.22515,683.05 L2417.22515,683.05 Z M2438.39992,686 L2438.39992,682.925 L2430.99992,682.925 L2430.99992,678.7 L2438.14992,678.7 L2438.14992,675.625 L2430.99992,675.625 L2430.99992,671.625 L2438.39992,671.625 L2438.39992,668.55 L2427.24992,668.55 L2427.24992,686 L2438.39992,686 Z M2453.82469,686 L2453.82469,682.925 L2446.32469,682.925 L2446.32469,668.55 L2442.54969,668.55 L2442.54969,686 L2453.82469,686 Z" id="VIEW-MODEL" fill="#FFFFFF" fill-rule="nonzero"></path>
<path d="M2162.90073,688 L2164.62073,677.76 L2169.38073,677.76 C2171.38073,677.76 2173.13407,677.346667 2174.64073,676.52 C2176.1474,675.693333 2177.3074,674.506667 2178.12073,672.96 C2178.93407,671.413333 2179.34073,669.586667 2179.34073,667.48 C2179.34073,665.266667 2178.68073,663.48 2177.36073,662.12 C2176.04073,660.76 2174.1674,660.08 2171.74073,660.08 L2171.74073,660.08 L2161.66073,660.08 L2156.98073,688 L2162.90073,688 Z M2168.54073,672.96 L2165.42073,672.96 L2166.78073,664.84 L2169.90073,664.84 C2171.07407,664.84 2171.91407,665.033333 2172.42073,665.42 C2172.9274,665.806667 2173.18073,666.453333 2173.18073,667.36 C2173.18073,667.76 2173.15407,668.12 2173.10073,668.44 L2173.10073,668.44 L2172.90073,669.64 C2172.71407,670.84 2172.28073,671.693333 2171.60073,672.2 C2170.92073,672.706667 2169.90073,672.96 2168.54073,672.96 L2168.54073,672.96 Z M2184.22037,688 L2186.98037,681.24 L2194.82037,681.24 L2195.50037,688 L2201.58037,688 L2198.54037,660.08 L2190.30037,660.08 L2178.02037,688 L2184.22037,688 Z M2194.58037,676.44 L2188.98037,676.44 L2193.38037,665.88 L2193.74037,665.88 L2194.58037,676.44 Z M2212.7,688.48 C2214.16667,688.48 2215.32667,688.106667 2216.18,687.36 C2217.03333,686.613333 2217.88667,685.48 2218.74,683.96 L2218.74,683.96 L2219.1,683.96 L2218.42,688 L2223.66,688 L2226.14,673.12 L2215.98,673.12 L2215.3,677.32 L2220.22,677.32 L2219.9,679.24 C2219.68667,680.52 2219.16,681.58 2218.32,682.42 C2217.48,683.26 2216.39333,683.68 2215.06,683.68 C2213.80667,683.68 2212.87333,683.266667 2212.26,682.44 C2211.64667,681.613333 2211.34,680.48 2211.34,679.04 C2211.34,678 2211.44667,676.84 2211.66,675.56 L2211.66,675.56 L2212.34,671.48 C2212.71333,669.213333 2213.33333,667.466667 2214.2,666.24 C2215.06667,665.013333 2216.23333,664.4 2217.7,664.4 C2218.95333,664.4 2219.84667,664.806667 2220.38,665.62 C2220.91333,666.433333 2221.23333,667.546667 2221.34,668.96 L2221.34,668.96 L2227.06,667.84 C2226.87333,665.306667 2226.04667,663.3 2224.58,661.82 C2223.11333,660.34 2220.99333,659.6 2218.22,659.6 C2215.44667,659.6 2213.08667,660.4 2211.14,662 C2209.19333,663.6 2207.73333,665.8 2206.76,668.6 C2205.78667,671.4 2205.3,674.6 2205.3,678.2 C2205.3,681.506667 2205.95333,684.046667 2207.26,685.82 C2208.56667,687.593333 2210.38,688.48 2212.7,688.48 Z M2246.85963,688 L2247.65963,683.12 L2235.69963,683.12 L2236.81963,676.32 L2248.29963,676.32 L2249.09963,671.44 L2237.65963,671.44 L2238.73963,664.96 L2250.73963,664.96 L2251.53963,660.08 L2233.69963,660.08 L2229.01963,688 L2246.85963,688 Z" id="PAGE" fill-opacity="0.85" fill="#000000" fill-rule="nonzero"></path>
<path d="M2329.5,408.732051 L2385.59069,441.116025 L2385.59069,505.883975 L2329.5,538.267949 L2273.40931,505.883975 L2273.40931,441.116025 L2329.5,408.732051 Z" id="Polygon-Copy-3" stroke="#55D4F5" stroke-width="3" fill="#FFFFFF"></path>
<path d="M2296.82052,471.24 C2298.20719,471.24 2299.30385,470.89 2300.11052,470.19 C2300.91719,469.49 2301.46719,468.5 2301.76052,467.22 L2301.76052,467.22 L2298.96052,466.54 C2298.78719,467.286667 2298.54052,467.853333 2298.22052,468.24 C2297.90052,468.626667 2297.41385,468.82 2296.76052,468.82 C2295.97385,468.82 2295.40385,468.513333 2295.05052,467.9 C2294.69719,467.286667 2294.52052,466.4 2294.52052,465.24 L2294.52052,465.24 L2294.52052,462.8 C2294.52052,461.64 2294.69719,460.753333 2295.05052,460.14 C2295.40385,459.526667 2295.97385,459.22 2296.76052,459.22 C2297.41385,459.22 2297.90052,459.413333 2298.22052,459.8 C2298.54052,460.186667 2298.78719,460.753333 2298.96052,461.5 L2298.96052,461.5 L2301.76052,460.82 C2301.46719,459.54 2300.91719,458.55 2300.11052,457.85 C2299.30385,457.15 2298.20719,456.8 2296.82052,456.8 C2294.98052,456.8 2293.60385,457.42 2292.69052,458.66 C2291.77719,459.9 2291.32052,461.686667 2291.32052,464.02 C2291.32052,466.353333 2291.77719,468.14 2292.69052,469.38 C2293.60385,470.62 2294.98052,471.24 2296.82052,471.24 Z M2308.50034,471.24 C2310.34034,471.24 2311.71034,470.62 2312.61034,469.38 C2313.51034,468.14 2313.96034,466.353333 2313.96034,464.02 C2313.96034,461.686667 2313.51034,459.9 2312.61034,458.66 C2311.71034,457.42 2310.34034,456.8 2308.50034,456.8 C2306.66034,456.8 2305.29034,457.42 2304.39034,458.66 C2303.49034,459.9 2303.04034,461.686667 2303.04034,464.02 C2303.04034,466.353333 2303.49034,468.14 2304.39034,469.38 C2305.29034,470.62 2306.66034,471.24 2308.50034,471.24 Z M2308.50034,468.82 C2307.687,468.82 2307.107,468.52 2306.76034,467.92 C2306.41367,467.32 2306.24034,466.426667 2306.24034,465.24 L2306.24034,465.24 L2306.24034,462.8 C2306.24034,461.613333 2306.41367,460.72 2306.76034,460.12 C2307.107,459.52 2307.687,459.22 2308.50034,459.22 C2309.31367,459.22 2309.89367,459.52 2310.24034,460.12 C2310.587,460.72 2310.76034,461.613333 2310.76034,462.8 L2310.76034,462.8 L2310.76034,465.22 C2310.76034,466.406667 2310.587,467.303333 2310.24034,467.91 C2309.89367,468.516667 2309.31367,468.82 2308.50034,468.82 Z M2319.72015,471 L2319.72015,461.7 L2319.78015,461.7 L2320.84015,463.9 L2323.50015,468.82 L2326.22015,463.88 L2327.24015,461.84 L2327.30015,461.84 L2327.30015,471 L2330.16015,471 L2330.16015,457.04 L2326.92015,457.04 L2323.54015,463.58 L2323.50015,463.58 L2320.08015,457.04 L2316.86015,457.04 L2316.86015,471 L2319.72015,471 Z M2337.04003,471 L2337.04003,465.92 L2339.42003,465.92 C2340.78003,465.92 2341.83336,465.523333 2342.58003,464.73 C2343.3267,463.936667 2343.70003,462.853333 2343.70003,461.48 C2343.70003,460.106667 2343.3267,459.023333 2342.58003,458.23 C2341.83336,457.436667 2340.78003,457.04 2339.42003,457.04 L2339.42003,457.04 L2334.02003,457.04 L2334.02003,471 L2337.04003,471 Z M2338.66003,463.5 L2337.04003,463.5 L2337.04003,459.46 L2338.66003,459.46 C2339.35336,459.46 2339.84003,459.593333 2340.12003,459.86 C2340.40003,460.126667 2340.54003,460.566667 2340.54003,461.18 L2340.54003,461.18 L2340.54003,461.78 C2340.54003,462.393333 2340.40003,462.833333 2340.12003,463.1 C2339.84003,463.366667 2339.35336,463.5 2338.66003,463.5 L2338.66003,463.5 Z M2350.49985,471.24 C2352.33985,471.24 2353.70985,470.62 2354.60985,469.38 C2355.50985,468.14 2355.95985,466.353333 2355.95985,464.02 C2355.95985,461.686667 2355.50985,459.9 2354.60985,458.66 C2353.70985,457.42 2352.33985,456.8 2350.49985,456.8 C2348.65985,456.8 2347.28985,457.42 2346.38985,458.66 C2345.48985,459.9 2345.03985,461.686667 2345.03985,464.02 C2345.03985,466.353333 2345.48985,468.14 2346.38985,469.38 C2347.28985,470.62 2348.65985,471.24 2350.49985,471.24 Z M2350.49985,468.82 C2349.68651,468.82 2349.10651,468.52 2348.75985,467.92 C2348.41318,467.32 2348.23985,466.426667 2348.23985,465.24 L2348.23985,465.24 L2348.23985,462.8 C2348.23985,461.613333 2348.41318,460.72 2348.75985,460.12 C2349.10651,459.52 2349.68651,459.22 2350.49985,459.22 C2351.31318,459.22 2351.89318,459.52 2352.23985,460.12 C2352.58651,460.72 2352.75985,461.613333 2352.75985,462.8 L2352.75985,462.8 L2352.75985,465.22 C2352.75985,466.406667 2352.58651,467.303333 2352.23985,467.91 C2351.89318,468.516667 2351.31318,468.82 2350.49985,468.82 Z M2365.69966,466.32 L2365.69966,463.48 L2359.29966,463.48 L2359.29966,466.32 L2365.69966,466.32 Z M2309.28037,496 L2309.28037,486.72 L2309.50037,486.72 L2312.68037,496 L2316.28037,496 L2316.28037,482.04 L2313.72037,482.04 L2313.72037,491.32 L2313.50037,491.32 L2310.32037,482.04 L2306.72037,482.04 L2306.72037,496 L2309.28037,496 Z M2328.02018,496 L2328.02018,493.54 L2322.10018,493.54 L2322.10018,490.16 L2327.82018,490.16 L2327.82018,487.7 L2322.10018,487.7 L2322.10018,484.5 L2328.02018,484.5 L2328.02018,482.04 L2319.10018,482.04 L2319.10018,496 L2328.02018,496 Z M2333.28,496 L2333.28,486.72 L2333.5,486.72 L2336.68,496 L2340.28,496 L2340.28,482.04 L2337.72,482.04 L2337.72,491.32 L2337.5,491.32 L2334.32,482.04 L2330.72,482.04 L2330.72,496 L2333.28,496 Z M2348.99982,496 L2348.99982,484.5 L2353.01982,484.5 L2353.01982,482.04 L2341.97982,482.04 L2341.97982,484.5 L2345.99982,484.5 L2345.99982,496 L2348.99982,496 Z" id="COMPO-NENT" fill-opacity="0.85" fill="#000000" fill-rule="nonzero"></path>
<g id="arrows-h-duotone" transform="translate(1464.000000, 424.000000)" fill="#55D4F5" fill-rule="nonzero">
<polygon id="Path" opacity="0.4" points="171.229979 51 33.7700213 51 23 40.5 33.7700213 30 171.229979 30 182 40.5"></polygon>
<path d="M154.149544,5.81775067 C152.752245,7.2774964 151.998196,9.23052018 152.054359,11.2443773 C152.110522,13.2582343 152.972263,15.1667635 154.448774,16.547372 L179.883362,40.496064 L154.448774,64.4447561 C152.972263,65.8253646 152.110522,67.7338937 152.054359,69.7477508 C151.998196,71.7616079 152.752245,73.7146317 154.149544,75.1743774 L157.749859,78.7709516 C160.750134,81.7430161 165.604646,81.7430161 168.604921,78.7709516 L200.008202,47.6575802 C201.923368,45.7627796 203,43.1879041 203,40.5023905 C203,37.8168769 201.923368,35.2420014 200.008202,33.3472008 L168.604921,2.22117653 C165.606495,-0.740392175 160.764201,-0.740392175 157.765775,2.22117653 L154.149544,5.81775067 Z M48.8345399,75.1743774 C50.231838,73.7146317 50.9858876,71.7616079 50.9297247,69.7477508 C50.8735617,67.7338937 50.0118201,65.8253646 48.5353094,64.4447561 L23.1007213,40.496064 L48.5353094,16.547372 C50.0118201,15.1667635 50.8735617,13.2582343 50.9297247,11.2443773 C50.9858876,9.23052018 50.231838,7.2774964 48.8345399,5.81775067 L45.2342246,2.22117653 C42.2376657,-0.729926874 37.4075545,-0.729926874 34.4109956,2.22117653 L2.99179846,33.3408743 C1.07663233,35.2356749 0,37.8105504 0,40.496064 C0,43.1815776 1.07663233,45.7564531 2.99179846,47.6512538 L34.3950791,78.7709516 C37.3935049,81.7325203 42.2357988,81.7325203 45.2342246,78.7709516 L48.8345399,75.1743774 Z" id="Shape"></path>
</g>
</g>
</svg>
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

#separationOfConcerns #singeResponsibility #scalability #compositionOverInheritance #looslyCoupled

An Event based Clean + MVVM Architecture for Plugin Apps

This document introduces the Clean + Model-View-View-Model (MVVM) front-end architecture will be using to develop Plugin Apps (micro-apps), in the Crate Solutions Single Page Web Application.

Introduction

Given future product plans, the Crate Analytics Platform (CAP) front-end architecture must be able to:

  • work for multiple clients
  • work for different business models
  • handle applications of a larger scope than the current client (Alpla)

Separating business related information in the application is our first action to take. For this, we're leveraging Clean Architecture[4] capabilities that describes us how to abstract away all the business data that becomes foundation of the application.

Building large-scale applications in JavaScript ecosystem has changed at least one fundamental way in the last few years. The one key concept that many developer adapted on is composition.(1) Functional paradigm is one of the agreement out of architecture proposal meetings and our architecture solution should favour composition over inheritance. Over the years we practiced with the component-based libraries like React, and frameworks like Vue and Angular. As a result we are familiar with modularising an application, composing components to build client-side JavaScript applications.

There is still a problem we need to compete. No matter how 3rd party component tools make easier the development, they don't impose any technique or approach how to organize your code base. They left it to whom use it. Model-View-ViewModel architecture is filling the gap for this requirement and tell us how to organize our application codebase at scale. MVVM is keeping Views free from business related information thanks to its ViewModels and those ViewModels are granular enough to contain particular informations. More general data will be dealt inside the Models at which state managers are fit in.

MVVM is enforcer of single responsibility. So that, it draws clear and self-evident boundaries around app components and models(2)

Last but not least, proposed architecture (Clean + MVVM Architecture) is a recipe how to glue business data with our component-based application and keeping them decoupled from each other.

Our components must be free from any direct business data manipulation. Decoupling business related information out of Application Logic will prevent scalability issues in future too.

Finally Events are channeling the information between tiers, without breaking decoupling nature of the architecture. At any given time, units (not the business related data, they're all about business concerns) emits and listens to events to carry information around.

Concepts Overview

Proposed architecture blends existing and proven techniques, and moves in the direction of a general method for building apps (2). It does not aim to impose new conventions or concepts, nor does it require us to introduce new roles/capabilities.

This is an event-based, 3-tier architecture. At the highest level, there are three topics

  • Domain,
  • Data,
  • and App for which guide application a structure. They are discussed in detail in the following section.

Domain Tier

Borrowed from Clean Architecture, this relates to building or forming business data.

Unlike Clean architecture constraints, the Domain layer is not the innermost nested layer, but the leftmost layer. It is independent from the development stack, and it must be written purely in the programming language.

The business related informations of the system, do not need to know what kind of application do they serve. Developers should focus on abstraction of business data while they working on the domain section.

Domain is the first place where separation of concern is coming in action.

Entity

Entities are meaningful pieces of information that map to the business you're dealing with. They're also known as business objects. An entity can be an object with methods, or it can be a set of data structures and functions(4). From that characteristics, we can say entities are used for encapsulating enterprise-wide, the most generic and high-level business rules.

Entities are the least likely to change when something external changes. For example, you would not expect these objects to be affected by a change to page navigation, or security. (4)

Use Cases

Use Cases are your business logic(1). To simply put, Business behaviours are defined as use cases and they generally used to complete a user's operation.

Use Cases coordinate the flow of data to and from the entity layer, and in the process achieve the goals of the use case by enforcing the entity's business rules. Changes to the use case (logic) do not affect the entity (rule). (7)

(Following sections are cited from this blogpost -- https://proandroiddev.com/why-you-need-use-cases-interactors-142e8a6fe576)

Useless Use Cases

Many times while writing use-cases, you end up use-cases are only wrapper for repositories. Even if they “do nothing” other than just calling a repository method, there are several reasons for still using them:

First: Consistency

Wouldn’t it be bad if some models would call use-cases while others would directly call repositories? Some less experienced developers or new joiners will have a hard time understanding what they are supposed to do while looking at the codebase.

Second: They protect the code from future changes

One of the purposes of Clean Architecture is to give you a codebase that can easily adapt when requirements change, which also means that the amount of code that needs to change should always be minimum.

If you skip creating use-cases, and using repositories directly in Models or worse in ViewModels, then when you require to update a repository for some reason, you're going to have to be make sure where this repository is used and make the changes accordingly.

Third, The “Screaming Architecture”

In most of the projects that you’ll see you won’t be able to understand what the app is about at first look. This might not bother you since maybe you started the project from scratch, but what about new joiners? How long will it take to them to understand what they have to do and how? Sake of predictability, and let your app screaming what it's doing, keep stick of the use-cases and repositories along with it.

A Use Case per Repository method?

This is a very common question and the answer is: most probably yes.

You don’t have a Use Case because you have a repository method, you have a repository method because you have a Use Case that needs it.

Clean Architecture is a Use Case driven architecture, hence each repository method exists only because it is supporting a Use Case.

It is also true that a Repository method should be used by one, Use Case so that if we get rid of a Use Case of the app then the persistence logic that is supporting it should disappear as well.

Now, I said you’ll “most probably” have a Use Case for each repository method, the reason why is not always true is that a Use Case can use more than one Repository and more than one method (as far as it is the only Use Case using them).

Data Tier

This is the aggregation tier where domain is used as inputs and prepared for the application state. It is also responsible of persisting/receiving data from outer sources, dealing data produced by application.

Data tier holds application-wide, purposeful, particular states along with requests the information from external sources like API.

Its purpose is deriving/containing a state and serving it throughout the application. Having said that, informations in the data tier must be general enough but contextual to serve all ends of application at any time. This constrain disallow you to put specific data in it. (This part will be explained in detail Model section)

Another function of data tier is encapsulating the persistent logic of your app. (This part will be explained in detail Repositories section)

Data tier can be dependant to our tooling and tech stack.

It is the location of which Single Responsibility feature

Data tier seeks Single Responsibility on its models.

Model

Model is the place where application states are created for a specific purpose. It uses domain entities and use-cases in order to create or derive the purposeful state for an application.

Being contextual is important for the Model. It should deal with all the aspects of a specific topic in the application(3). Mixture of different concerns is discouraged.

Models are units where we're committing Single Responsibility characteristic of the Architecture. So to say, if your Model is spanning responsibilities of more than one context than you are at risk that ending up fat, God Model that contain everything. It's clear violation of single responsibility, besides that makes getting harder to scale for future.

Best practice is keeping your concerns in a different models and allow models to negotiate each other. That communication can be happen via Events or you can leverage any tooling capability to achieve it.

A Model can only and should communicate another Models or ViewModels. Otherwise Model's consistency would compromised by unintended behaviour.

Global Model

Let's discuss the necessity of the global state for the application. In fact it's necessary most of the time for an Frontend Application. But the architecture we discuss has mechanism to eliminate that need:

  • Models can communicate each other via their Event Channel
  • Single Responsibility concern forces us create multiple models for different contexts.

Global Model is in this architecture is nothing more than "yet another" model. It holds its own concerns that cannot fit other Models and it can share its common data with other models. Given this example this Global model is not different from other models.

Possible replacement with State Managers

Suggested mechanism for Models is using event channels sending/receiving data from and to Models and ViewModels. Even though using events are convenient, one would like to use a state manager library and deals the creating and deriving state job by using it.

Using external state manager is still subject to fulfil architecture's expectations and follow its instructions for integrity. Having said that, State manager in the Model must not accessed by Views but ViewModels, State manager must configured to contain contextual and purposeful data, not be used as Global Object.

This is usually a cumbersome task. These state managers are designed to work directly inside the components. That's most likely cause collision. In this architecture, We're abstracted all the application data into ViewModels. That means you will end up using state manager only in the ViewModel but keeping away directly from View (component).

This abstraction may seem unnecessary effort at first sight, but in the long run, it will be a win. Consider yourself refactoring a class components to a function components in react.js. Imagine how hard it could be replacing entire content including component logic, state data and other intertwined parts of the components. If you followed the architecture rules and keeping every data related thing inside the ViewModel, you were only worried the Component itself and all others are already dealt inside the ViewModel.

Another challenging task would be using multiple stores for different contexts and communicate them each other. Architecture we discuss here suggests to using events for this need. When you go for a tech to replace models with 3rd party state manager, it will now up to you how to establish this communication mechanism between models. From then on architecture only enforces you to follow its rules.

Repository

Repositories are persistent logic containers. Since we're developing this architecture for Frontend Apps, persistence means API usage and Browser storage usage.

Repositories are used by Use Cases and they're instruments for the completing a use case duties.

Another important feature is they're injected in use cases in runtime. A use case will not have hard dependency a repository. Model is the place where you should inject the repository in a use case

App Tier

(to be written)

View Model

(to be written)

View

(to be written)

Structure

Clean + MVVM Architecture is not dictating Layered, Union architectures like Clean Architecture does. All tiers (Domain - Data - Application) are in same, horizontal level.

Domain holds and defines business rules and logics via entities and use-cases. Data tier consumes the Domain tier and creates application states for specific responsibilities (mind the plural states here. Architecture tries to avoid putting everything into a one, global state). Data tier is also encapsulates all the persistence logic with Repositories. App tier in which consists of ViewModels and Views interacts with Data tier and presents the application state to the end user. App tier is able to mutate the application state by user interactions.

Data flow

MVVM uses a half-duplex and sequential data flow, in the form of events which move between respective channels. The Data and App layers therefore need to be capable of sending events to one another. The following data flow constraints apply:

  • Views can only send or receive events from their ViewModels.
  • ViewModels can send or receive events from at least one or multiple Models.
  • ViewModels should not share data each other. Even though it's possible through events, it's an obvious violation of data flow. That causes traceability issues of information.
  • Models shares their data each other. They do that their respective event channels.

EventBus

EventBus is a general term that references the event channels between units. Views communicate their ViewModels via events, therefore they using EventBus. Same mechanism goes for ViewModel - Model communication as well as Model - Model communication. Please consult the PoC here (https://github.com/crate/crate-solutions-ui-mvvm-poc) to see how EventBus is working in action.

Pod

Finally, MVVM groups contextual elements together as pods. Pod elements are closely thematically related, and using them can make it easy to manage files and folder structure during development(2).

Generally pods are forming of multiple Views and ViewModels and they can be extended to including their own Model. It's very depend on the occasion and it should be beneficial if you group them together.


Resources

(1) https://medium.com/google-developers/javascript-application-architecture-on-the-road-to-2015-d8125811101b

(2) http://vieux.io/

(3) https://github.com/bailabs/react_js_clean_architecture

(4) https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html

(5) https://yuriktech.com/2019/06/11/Implementing-Clean-Architecture/

(6) https://proandroiddev.com/why-you-need-use-cases-interactors-142e8a6fe576

(7) https://phodal.github.io/clean-frontend/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment