כיצד לבנות עסק פונקציונלי

גלה JavaScript פונקציונלי הוכר על ידי BookAuthority כאחד הספרים הטובים ביותר בנושא תכנות פונקציונלי!

צילום מאת אוגור אקדמיר על Unsplash

פונקציות טהורות מייצרות את אותו ערך פלט עם אותו קלט. אין להם תופעות לוואי וקל יותר לקרוא, להבין ולבדוק.

עם זאת, ברצוני להקים חנות שמסתירה סטטוס אך משתמשת בפונקציונליות טהורה בו זמנית.

חוסר שינוי

פונקציות טהורות אינן משנות את קלטן. הם מתייחסים לערכי הקלט כבלתי ניתנים לשינוי.

ערך בלתי ניתן לשינוי הוא ערך שלא ניתן לשנות לאחר יצירתו.

Immutable.js מספק מבני נתונים בלתי ניתנים לשינוי כמו List. מבנה נתונים שאינו משתנה יוצר מבנה נתונים חדש עם כל פעולה.

שקול את הקוד הבא:

ייבא את {list} מ- "immutable";
const list = רשימה (); const newList = list.push (1);

push () יוצר רשימה חדשה עם האלמנט החדש. הרשימה הקיימת לא שונתה.

מחק () מחזירה רשימה חדשה בה האלמנט באינדקס שצוין הוסר.

מבנה נתוני הרשימה מספק ממשק נחמד לעבודה עם רשימות שאינן ניתנות לשינוי, ולכן אשתמש בו כערך סטטוס.

העסק

החנות מנהלת מדינה.

סטטוס הם נתונים שיכולים להשתנות. החנות מסתירה את נתוני הסטטוס הללו ומספקת קבוצה ציבורית של שיטות לעבודה איתם.

אני רוצה ליצור חנות ספרים בשיטות הוספה (), הסרה () ו- getBy ().

אני רוצה שכל הפונקציות הללו יהיו פונקציות טהורות.

ישנם שני סוגים של פונקציות טהורות המשמשות עסקים:

  • פונקציות שקוראות ומסננות את הסטטוס. אני אקרא להם גטרים.
  • פונקציות שמשנות את המצב. אני אקרא להם קובעים.

שני סוגי הפונקציות לוקחים את הסטטוס כפרמטר הראשון.

בואו נכתוב את החנות עם פונקציות טהורות.

ייבא את {list} מ- "immutable"; יבוא חלקי מ"לאדאש / חלקי "; יבוא גפרורים נכס מ lodash / matchesProperty;
// הוסף פונקציית קובעת (ספרים, ספר) {return books.push (ספר); }
הסר פונקציה (ספרים, ספר) {const index = books.findIndex (matchesProperty ("id", book.id)); להחזיר ספרים. מחק (אינדקס); }
// query פונקציית GetterContainsBook (שאילתה, ספר) {if (query && query.text) {return book.title.includes (query.text); } להחזיר אמת; }
פונקציה getBy (ספרים, שאילתה) {return books.filter (באופן חלקי (queryContainsBook, שאילתה)). toArray (); }

הספרייה

הסטטוס צריך להיות מוסתר באובייקט העסקי. אני לא רוצה לשלוח את הסטטוס לאובייקט העסקי מבחוץ. יחד עם זאת, אני רוצה לנצל את מלוא הפונקציות הטהורות ולהשתמש בהן להגדרת שיטות האחסון.

כיצד ניתן להשיג זאת?

ראינו את התשובה ב- Redux. אנו כותבים פונקציות טהורות ונותנים לספריה ליצור את הזיכרון ולהשתמש בפונקציות הטהורות.

כך אני רוצה להשתמש בספרייה כדי להגדיר את העסק:

ייבא את {list} מ- "immutable"; ייבא חנות מ- "./Store-toolbox";
// הוסף פונקציית קובעת (ספרים, ספר) {} הסר פונקציה (ספרים, ספר) {}
// פונקציית Getter getBy (ספרים, שאילתה) {}
ייצא זיכרון סטנדרטי ({state: List (), Setter: {add, remove}, Getter: {getBy}});

בואו ניצור מיקרו-ספרייה זו שתבנה את החנות על בסיס הגטרים והסטרים הטהורים.

כל הקבוצות והקובעים הציבוריים מעוטרים ומקבלים את הסטטוס כפרמטר הראשון.

  • ערך ההחזרה של הגטרים מוחזר לפונקציות המתקשרים.
  • הערך שהוחזר על ידי סטטרים משמש לשינוי הסטטוס. פונקציות המתקשרים אינן מקבלות את הסטטוס החדש.
פונקציה decorateMethods (obj, decorator) {let newObject = {... obj};
Object.keys (newObject) .forEach (function decorateMethod (fnName) {if (typeof newObject [fnName] === "function") {newObject [fnName] = decorator (newObject [fnName]);}});
להחזיר newObject; }
חנות פונקציות (storeConfig) {פונקצית החזרה () {let state = storeConfig.state;
קובץ פונקציות (fn) {פונקציית החזרה (... args) {state = fn (state, ... args); }; }
פונקציה getter (fn) {פונקציית return (... args) {return fn (state, ... args); }; }
החזר Object.freeze ({... decorateMethods (storeConfig.getters, getter), ... decorateMethods (storeConfig.setters, setter)}); }; }
ייצוא אחסון סטנדרטי;

חנות () יוצרת פונקציה המחזירה אובייקט העוטף את המצב.

צור והשתמש באובייקט bookStore:

ייבא את BookStore מ- "./BookStore";
const bookStore = BookStore (); bookStore.add ({id: 1, כותרת: "איך JavaScript עובד"});

כאשר קוראים ל- bookStore.add ({}), מעצב הקובעים מכנה את פונקציית הקובע add () טהור עם המצב הנוכחי כפרמטר הראשון והספר החדש כפרמטר השני. ואז מעצב הקובעים משתמש בתוצאה כדי לשנות את ערך המדינה.

האובייקט

בואו ננתח את אובייקט bookStore.

שלוש שיטות בלבד זמינות, כל שאר הפונקציות הטהורות פרטיות.

לא ניתן לשנות את הממשק הציבורי של האובייקט מבחוץ.

המדינה מוסתרת. הלקוחות המשתמשים באובייקט bookStore יכולים לגשת למצב רק בשיטות הציבוריות.

סיכום

קל יותר להבין פונקציות טהורות.

בעזרת ספרייה אנו יכולים ליצור זיכרון שמסתיר את המצב ומשתמש בפונקציות טהורות.

אנחנו יכולים פשוט לכתוב את הפונקציות הטהורות ולתת לספריה להשתמש בהן ולעשות את המוטציה.

אתה יכול לבדוק את קוד הדוגמה ב- codesandbox.io.

גלה JavaScript פונקציונלי הוכר על ידי BookAuthority כאחד הספרים הטובים ביותר בנושא תכנות פונקציונלי!

למידע נוסף על החלת טכניקות פונקציונליות על תגובה, ראה תגובה פונקציונלית.

למד כיצד ליישם את עקרונות דפוסי העיצוב.

תוכלו למצוא אותי בטוויטר.