برنامه نویسی

برنامه نویسی داده گرا چیست؟

Summarize this content to 400 words in Persian Lang
برنامه نويسي برنامه نویسی داده گرا (DOP) یک رویکرد برنامه نویسی است که بر ترتیب ساختارهای داده و الگوریتم هایی که بر روی آنها کار می کنند متمرکز است تا در هنگام دسترسی و پردازش مقادیر زیادی از داده ها بیشترین کارایی را داشته باشند. تاکید بر جداسازی داده ها و کد است.

4 اصل اصلی DOP عبارتند از:

کد را از داده ها جدا کنید
داده ها را با ساختار داده های عمومی ارائه دهید
اطلاعات را ویرایش نکنید.
طرح واره داده را از نمایش داده جدا کنید.

نمونه کد جاوا اسکریپت

const sqlite3 = require(‘sqlite3’).verbose();

// Immutable data structures
const createBook = (id, title, author) => Object.freeze({id, title, author});
const createLibrary = (name, books) => Object.freeze({name, books});

// Database operations
const initDB = () => {
return new Promise((resolve, reject) => {
const db = new sqlite3.Database(‘./library.db’, (err) => {
if (err) reject(err);
db.run(`CREATE TABLE IF NOT EXISTS books (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT,
author TEXT
)`, (err) => {
if (err) reject(err);
resolve(db);
});
});
});
};

// Generic data manipulation functions
const addBook = (db, title, author) => {
return new Promise((resolve, reject) => {
db.run(‘INSERT INTO books (title, author) VALUES (?, ?)’, [title, author], function(err) {
if (err) reject(err);
resolve(createBook(this.lastID, title, author));
});
});
};

const removeBook = (db, id) => {
return new Promise((resolve, reject) => {
db.run(‘DELETE FROM books WHERE id = ?’, [id], (err) => {
if (err) reject(err);
resolve();
});
});
};

const getAllBooks = (db) => {
return new Promise((resolve, reject) => {
db.all(‘SELECT * FROM books’, (err, rows) => {
if (err) reject(err);
resolve(rows.map(row => createBook(row.id, row.title, row.author)));
});
});
};

// Behavior (pure functions that don’t modify data directly)
const displayLibrary = (library) => {
console.log(`Library: ${library.name}`);
library.books.forEach(book => {
console.log(`- ${book.title} by ${book.author} (ID: ${book.id})`);
});
};

// Main execution
async function main() {
try {
const db = await initDB();

// Add initial books
await addBook(db, “1984”, “George Orwell”);
await addBook(db, “To Kill a Mockingbird”, “Harper Lee”);

// Get all books and display library
let books = await getAllBooks(db);
let library = createLibrary(“City Library”, books);

console.log(“Initial Library:”);
displayLibrary(library);

// Add a new book
const newBook = await addBook(db, “The Great Gatsby”, “F. Scott Fitzgerald”);
library = createLibrary(library.name, […library.books, newBook]);

console.log(“\nAfter adding a book:”);
displayLibrary(library);

// Remove a book
await removeBook(db, 1);

// Get updated books and display library
books = await getAllBooks(db);
library = createLibrary(library.name, books);

console.log(“\nAfter removing a book:”);
displayLibrary(library);

db.close();
} catch (error) {
console.error(“An error occurred:”, error);
}
}

main();

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

از مثال:

داده های تغییرناپذیر: استفاده کنید Object.freeze() برای ایجاد اشیاء تغییرناپذیر که برای ایجاد کتاب و کتابخانه قابل ویرایش نیستند.

جداسازی داده ها و رفتار: اطلاعات (books و library) از توابع مورد پردازش جدا شده است.

ساختارهای داده عمومی: از انواع داده های ساده مانند اشیا و آرایه ها استفاده کنید.

توابع دستکاری داده ها: عملکردهای مختلف addBook، removeBook و findBook بدون تغییر مستقیم داده ها با داده ها کار کنید، فقط مقادیر را دریافت کرده و آنها را فوروارد کنید.

توابع خالص: همه توابع خالص هستند، هیچ عوارض جانبی ندارند و همیشه به جای ویرایش داده ها، داده های جدید را بازیابی می کنند.

داده های متمرکز: libraryData این یک متغیر است که با ذخیره‌گاه داده‌های مرکزی کار می‌کند، در این مثال، sqlite با برگرداندن نتایج از توابع خالص، مقادیر جدیدی را تغییر می‌دهد.

برو مثال زبان

package main

import (
“database/sql”
“fmt”
“log”

_ “github.com/mattn/go-sqlite3”
)

// Immutable data structures
type Book struct {
ID int
Title string
Author string
}

type Library struct {
Name string
Books []Book
}

// Database operations
func initDB(dbPath string) (*sql.DB, error) {
db, err := sql.Open(“sqlite3”, dbPath)
if err != nil {
return nil, err
}

_, err = db.Exec(`
CREATE TABLE IF NOT EXISTS books (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT,
author TEXT
)
`)
if err != nil {
return nil, err
}

return db, nil
}

// Generic data manipulation functions
func addBook(db *sql.DB, title, author string) (Book, error) {
result, err := db.Exec(“INSERT INTO books (title, author) VALUES (?, ?)”, title, author)
if err != nil {
return Book{}, err
}

id, err := result.LastInsertId()
if err != nil {
return Book{}, err
}

return Book{ID: int(id), Title: title, Author: author}, nil
}

func removeBook(db *sql.DB, id int) error {
_, err := db.Exec(“DELETE FROM books WHERE id = ?”, id)
return err
}

func getAllBooks(db *sql.DB) ([]Book, error) {
rows, err := db.Query(“SELECT id, title, author FROM books”)
if err != nil {
return nil, err
}
defer rows.Close()

var books []Book
for rows.Next() {
var b Book
err := rows.Scan(&b.ID, &b.Title, &b.Author)
if err != nil {
return nil, err
}
books = append(books, b)
}

return books, nil
}

// Behavior (pure functions that don’t modify data directly)
func displayLibrary(library Library) {
fmt.Printf(“Library: %s\n”, library.Name)
for _, book := range library.Books {
fmt.Printf(“- %s by %s (ID: %d)\n”, book.Title, book.Author, book.ID)
}
}

func main() {
db, err := initDB(“library.db”)
if err != nil {
log.Fatal(err)
}
defer db.Close()

// Add books
_, err = addBook(db, “1984”, “George Orwell”)
if err != nil {
log.Fatal(err)
}
_, err = addBook(db, “To Kill a Mockingbird”, “Harper Lee”)
if err != nil {
log.Fatal(err)
}

// Get all books and display library
books, err := getAllBooks(db)
if err != nil {
log.Fatal(err)
}

library := Library{Name: “City Library”, Books: books}
fmt.Println(“Initial Library:”)
displayLibrary(library)

// Add a new book
newBook, err := addBook(db, “The Great Gatsby”, “F. Scott Fitzgerald”)
if err != nil {
log.Fatal(err)
}
library.Books = append(library.Books, newBook)

fmt.Println(“\nAfter adding a book:”)
displayLibrary(library)

// Remove a book
err = removeBook(db, 1)
if err != nil {
log.Fatal(err)
}

// Get updated books and display library
library.Books, err = getAllBooks(db)
if err != nil {
log.Fatal(err)
}

fmt.Println(“\nAfter removing a book:”)
displayLibrary(library)
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

از مثال کد DOP، این یک برنامه کاربردی از برنامه نویسی کاربردی برای کمک به سازماندهی سوابق کدگذاری با جداسازی داده ها و رفتار است.

استحکام – قدرت

قابل انعطاف هنگامی که می خواهید پایگاه داده را از Sqlite به پایگاه داده دیگری که از زبان SQL پشتیبانی می کند تغییر دهید، می توانید آن را در قسمت db object تغییر دهید. import _ “github.com/mattn/go-sqlite3” بله، اما نمونه های جاوا اسکریپت هنوز برای انعطاف پذیری طراحی نشده اند. هنوز باید بسیاری از نکات را تغییر دهید اما طراحی کد را به این صورت خواهید دید به سازماندهی بیشتر کمک می کند.

خیلی راحت تر میشه تست کرد می توان از آن برای نوشتن تست ها به راحتی استفاده کرد زیرا هر تابع ورودی را دریافت می کند و داده هایی را برمی گرداند که به راحتی می توانند برای تهیه داده ها کدگذاری شوند و برای بررسی پاسخ ها اظهار نظر کنند.

استفاده مجدد به راحتی قابل استفاده مجدد یا مونتاژ در عملکردهای جدید است.

افزایش بهره وری الگویی وجود دارد که هنگام کار به شیوه ای مشابه یا با یک تیم خیلی پیچیده نیست. ایجاد یک دست خط برای کل تیم آسان است. کد برای خواندن آسان به همین ترتیب بنویسید

کاهش عوارض جانبی اطمینان حاصل کنید که کد به درستی کار می کند و توسط توابع دیگر تغییر نکرده است.

ضعف

سربار عملکرد هر ایجاد اشیاء تغییرناپذیر جدید، بسته به توانایی زبان در مدیریت این حافظه، استفاده از حافظه را افزایش می دهد. ممکن است برخی از زبان ها تحت تأثیر قرار نگیرند.

برخی از سناریوهای پیچیده ممکن است مناسب نباشند. فرمت DOP برای کارهایی که مستقیماً با منبع داده کار می کند، ذخیره داده که برای تناسب با ساختار داده پردازش می شود، کاملاً مناسب است. در برخی از برنامه‌های کاربردی که دارای طرح‌ها و ساختارهای پیچیده‌ای هستند که مستقیماً مشابه منبع داده نیستند، مانند برنامه‌های OOP، این ممکن است دشوار باشد و پیچیدگی را فراتر از ضرورت افزایش دهد.

احتمال ناسازگاری داده ها تغییرناپذیر برای حذف بدون تغییر داده ها برای پایگاه داده سنتی که استفاده می شود مناسب نیست. اگر می‌خواهیم رویکردهای کد و پایگاه داده هماهنگ باشند، باید طرز تفکر را تغییر داد یا از یک پایگاه داده غیرقابل تغییر استفاده کرد. اگر داده های کد و مفهوم متناقض باشند، داده ها سازگاری ندارند.

مشکل در نمایش اشیاء حالت دار: ممکن است کار با سایر سیستم های حالت دار را دشوار کند.

استفاده بیش از حد بالقوه از ساختارهای داده عمومی: استفاده بیش از حد از داده های عمومی، ممکن است برای همه کارها به داده های عمومی نیاز نباشد.

هر الگوی مزایا و معایب متفاوتی دارد. یکی را انتخاب کنید که فکر می کنید برای کار مناسب است و می تواند مشکل را بدون اضافه کردن به مشکل حل کند. همانطور که می بینید، DOP برای کارهایی که نیاز به برنامه نویسی دارند، بسته به ساختار داده ای که نیاز به تعامل مستقیم با ذخیره داده ها دارد، مناسب است.

برنامه نويسي برنامه نویسی داده گرا (DOP) یک رویکرد برنامه نویسی است که بر ترتیب ساختارهای داده و الگوریتم هایی که بر روی آنها کار می کنند متمرکز است تا در هنگام دسترسی و پردازش مقادیر زیادی از داده ها بیشترین کارایی را داشته باشند. تاکید بر جداسازی داده ها و کد است.

4 اصل اصلی DOP عبارتند از:

  1. کد را از داده ها جدا کنید
  2. داده ها را با ساختار داده های عمومی ارائه دهید
  3. اطلاعات را ویرایش نکنید.
  4. طرح واره داده را از نمایش داده جدا کنید.

اصل DOP

نمونه کد جاوا اسکریپت

const sqlite3 = require('sqlite3').verbose();

// Immutable data structures
const createBook = (id, title, author) => Object.freeze({id, title, author});
const createLibrary = (name, books) => Object.freeze({name, books});

// Database operations
const initDB = () => {
  return new Promise((resolve, reject) => {
    const db = new sqlite3.Database('./library.db', (err) => {
      if (err) reject(err);
      db.run(`CREATE TABLE IF NOT EXISTS books (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        title TEXT,
        author TEXT
      )`, (err) => {
        if (err) reject(err);
        resolve(db);
      });
    });
  });
};

// Generic data manipulation functions
const addBook = (db, title, author) => {
  return new Promise((resolve, reject) => {
    db.run('INSERT INTO books (title, author) VALUES (?, ?)', [title, author], function(err) {
      if (err) reject(err);
      resolve(createBook(this.lastID, title, author));
    });
  });
};

const removeBook = (db, id) => {
  return new Promise((resolve, reject) => {
    db.run('DELETE FROM books WHERE id = ?', [id], (err) => {
      if (err) reject(err);
      resolve();
    });
  });
};

const getAllBooks = (db) => {
  return new Promise((resolve, reject) => {
    db.all('SELECT * FROM books', (err, rows) => {
      if (err) reject(err);
      resolve(rows.map(row => createBook(row.id, row.title, row.author)));
    });
  });
};

// Behavior (pure functions that don't modify data directly)
const displayLibrary = (library) => {
  console.log(`Library: ${library.name}`);
  library.books.forEach(book => {
    console.log(`- ${book.title} by ${book.author} (ID: ${book.id})`);
  });
};

// Main execution
async function main() {
  try {
    const db = await initDB();

    // Add initial books
    await addBook(db, "1984", "George Orwell");
    await addBook(db, "To Kill a Mockingbird", "Harper Lee");

    // Get all books and display library
    let books = await getAllBooks(db);
    let library = createLibrary("City Library", books);

    console.log("Initial Library:");
    displayLibrary(library);

    // Add a new book
    const newBook = await addBook(db, "The Great Gatsby", "F. Scott Fitzgerald");
    library = createLibrary(library.name, [...library.books, newBook]);

    console.log("\nAfter adding a book:");
    displayLibrary(library);

    // Remove a book
    await removeBook(db, 1);

    // Get updated books and display library
    books = await getAllBooks(db);
    library = createLibrary(library.name, books);

    console.log("\nAfter removing a book:");
    displayLibrary(library);

    db.close();
  } catch (error) {
    console.error("An error occurred:", error);
  }
}

main();
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

از مثال:

  • داده های تغییرناپذیر: استفاده کنید Object.freeze() برای ایجاد اشیاء تغییرناپذیر که برای ایجاد کتاب و کتابخانه قابل ویرایش نیستند.
  • جداسازی داده ها و رفتار: اطلاعات (books و library) از توابع مورد پردازش جدا شده است.
  • ساختارهای داده عمومی: از انواع داده های ساده مانند اشیا و آرایه ها استفاده کنید.
  • توابع دستکاری داده ها: عملکردهای مختلف addBook، removeBook و findBook بدون تغییر مستقیم داده ها با داده ها کار کنید، فقط مقادیر را دریافت کرده و آنها را فوروارد کنید.
  • توابع خالص: همه توابع خالص هستند، هیچ عوارض جانبی ندارند و همیشه به جای ویرایش داده ها، داده های جدید را بازیابی می کنند.
  • داده های متمرکز: libraryData این یک متغیر است که با ذخیره‌گاه داده‌های مرکزی کار می‌کند، در این مثال، sqlite با برگرداندن نتایج از توابع خالص، مقادیر جدیدی را تغییر می‌دهد.

برو مثال زبان

package main

import (
    "database/sql"
    "fmt"
    "log"

    _ "github.com/mattn/go-sqlite3"
)

// Immutable data structures
type Book struct {
    ID     int
    Title  string
    Author string
}

type Library struct {
    Name  string
    Books []Book
}

// Database operations
func initDB(dbPath string) (*sql.DB, error) {
    db, err := sql.Open("sqlite3", dbPath)
    if err != nil {
        return nil, err
    }

    _, err = db.Exec(`
        CREATE TABLE IF NOT EXISTS books (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            title TEXT,
            author TEXT
        )
    `)
    if err != nil {
        return nil, err
    }

    return db, nil
}

// Generic data manipulation functions
func addBook(db *sql.DB, title, author string) (Book, error) {
    result, err := db.Exec("INSERT INTO books (title, author) VALUES (?, ?)", title, author)
    if err != nil {
        return Book{}, err
    }

    id, err := result.LastInsertId()
    if err != nil {
        return Book{}, err
    }

    return Book{ID: int(id), Title: title, Author: author}, nil
}

func removeBook(db *sql.DB, id int) error {
    _, err := db.Exec("DELETE FROM books WHERE id = ?", id)
    return err
}

func getAllBooks(db *sql.DB) ([]Book, error) {
    rows, err := db.Query("SELECT id, title, author FROM books")
    if err != nil {
        return nil, err
    }
    defer rows.Close()

    var books []Book
    for rows.Next() {
        var b Book
        err := rows.Scan(&b.ID, &b.Title, &b.Author)
        if err != nil {
            return nil, err
        }
        books = append(books, b)
    }

    return books, nil
}

// Behavior (pure functions that don't modify data directly)
func displayLibrary(library Library) {
    fmt.Printf("Library: %s\n", library.Name)
    for _, book := range library.Books {
        fmt.Printf("- %s by %s (ID: %d)\n", book.Title, book.Author, book.ID)
    }
}

func main() {
    db, err := initDB("library.db")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    // Add books
    _, err = addBook(db, "1984", "George Orwell")
    if err != nil {
        log.Fatal(err)
    }
    _, err = addBook(db, "To Kill a Mockingbird", "Harper Lee")
    if err != nil {
        log.Fatal(err)
    }

    // Get all books and display library
    books, err := getAllBooks(db)
    if err != nil {
        log.Fatal(err)
    }

    library := Library{Name: "City Library", Books: books}
    fmt.Println("Initial Library:")
    displayLibrary(library)

    // Add a new book
    newBook, err := addBook(db, "The Great Gatsby", "F. Scott Fitzgerald")
    if err != nil {
        log.Fatal(err)
    }
    library.Books = append(library.Books, newBook)

    fmt.Println("\nAfter adding a book:")
    displayLibrary(library)

    // Remove a book
    err = removeBook(db, 1)
    if err != nil {
        log.Fatal(err)
    }

    // Get updated books and display library
    library.Books, err = getAllBooks(db)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("\nAfter removing a book:")
    displayLibrary(library)
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

از مثال کد DOP، این یک برنامه کاربردی از برنامه نویسی کاربردی برای کمک به سازماندهی سوابق کدگذاری با جداسازی داده ها و رفتار است.

استحکام – قدرت

  1. قابل انعطاف هنگامی که می خواهید پایگاه داده را از Sqlite به پایگاه داده دیگری که از زبان SQL پشتیبانی می کند تغییر دهید، می توانید آن را در قسمت db object تغییر دهید. import _ "github.com/mattn/go-sqlite3" بله، اما نمونه های جاوا اسکریپت هنوز برای انعطاف پذیری طراحی نشده اند. هنوز باید بسیاری از نکات را تغییر دهید اما طراحی کد را به این صورت خواهید دید به سازماندهی بیشتر کمک می کند.
  2. خیلی راحت تر میشه تست کرد می توان از آن برای نوشتن تست ها به راحتی استفاده کرد زیرا هر تابع ورودی را دریافت می کند و داده هایی را برمی گرداند که به راحتی می توانند برای تهیه داده ها کدگذاری شوند و برای بررسی پاسخ ها اظهار نظر کنند.
  3. استفاده مجدد به راحتی قابل استفاده مجدد یا مونتاژ در عملکردهای جدید است.
  4. افزایش بهره وری الگویی وجود دارد که هنگام کار به شیوه ای مشابه یا با یک تیم خیلی پیچیده نیست. ایجاد یک دست خط برای کل تیم آسان است. کد برای خواندن آسان به همین ترتیب بنویسید
  5. کاهش عوارض جانبی اطمینان حاصل کنید که کد به درستی کار می کند و توسط توابع دیگر تغییر نکرده است.

ضعف

  1. سربار عملکرد هر ایجاد اشیاء تغییرناپذیر جدید، بسته به توانایی زبان در مدیریت این حافظه، استفاده از حافظه را افزایش می دهد. ممکن است برخی از زبان ها تحت تأثیر قرار نگیرند.
  2. برخی از سناریوهای پیچیده ممکن است مناسب نباشند. فرمت DOP برای کارهایی که مستقیماً با منبع داده کار می کند، ذخیره داده که برای تناسب با ساختار داده پردازش می شود، کاملاً مناسب است. در برخی از برنامه‌های کاربردی که دارای طرح‌ها و ساختارهای پیچیده‌ای هستند که مستقیماً مشابه منبع داده نیستند، مانند برنامه‌های OOP، این ممکن است دشوار باشد و پیچیدگی را فراتر از ضرورت افزایش دهد.
  3. احتمال ناسازگاری داده ها تغییرناپذیر برای حذف بدون تغییر داده ها برای پایگاه داده سنتی که استفاده می شود مناسب نیست. اگر می‌خواهیم رویکردهای کد و پایگاه داده هماهنگ باشند، باید طرز تفکر را تغییر داد یا از یک پایگاه داده غیرقابل تغییر استفاده کرد. اگر داده های کد و مفهوم متناقض باشند، داده ها سازگاری ندارند.
  4. مشکل در نمایش اشیاء حالت دار: ممکن است کار با سایر سیستم های حالت دار را دشوار کند.
  5. استفاده بیش از حد بالقوه از ساختارهای داده عمومی: استفاده بیش از حد از داده های عمومی، ممکن است برای همه کارها به داده های عمومی نیاز نباشد.

هر الگوی مزایا و معایب متفاوتی دارد. یکی را انتخاب کنید که فکر می کنید برای کار مناسب است و می تواند مشکل را بدون اضافه کردن به مشکل حل کند. همانطور که می بینید، DOP برای کارهایی که نیاز به برنامه نویسی دارند، بسته به ساختار داده ای که نیاز به تعامل مستقیم با ذخیره داده ها دارد، مناسب است.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا