نظرات مطالب
Blazor 5x - قسمت 34 - توزیع برنامه‌های Blazor بر روی IIS
یک نکته‌ی تکمیلی: کاربرد base href در فایل index.html چیست؟

فرض کنید برنامه‌ی شما قرار است از داخل زیر پوشه‌ی جدید blazor با آدرس http://example.com/blazor ارائه شود. در این حالت پس از مراجعه به این آدرس، فقط loading را مشاهده خواهید کرد و ... برنامه بارگذاری نمی‌شود. علت اینجا است که در حالت پیش‌فرض، base href تنظیم شده‌ی در فایل index.html، به ریشه‌ی سایت اشاره می‌کند:
<!DOCTYPE html>
<html>
<head>
   <base href="/" />
بنابراین در این حالت برنامه فایل‌های مورد نیاز خود را در ریشه‌ی وب سرور جستجو خواهد کرد و نه از زیر پوشه‌ی blazor. برای رفع این مشکل باید تغییر زیر صورت گیرد:
<base href="/blazor/" />
مطالب
استفاده از Froala WYSIWYG Editor در ASP.NET
چندی قبل، معرفی ادیتور سبک وزن و مناسبی را تحت عنوان RedActor، در این سایت ملاحظه کردید. زمانیکه این‌کار انجام شد، این ادیتور هم رایگان بود و هم سورس آخرین نگارش آن به سادگی در دسترس. بعد از مدتی، هر دو ویژگی یاد شده‌ی RedActor حذف شدند. پس از آن ادیتور مدرن و بسیار مناسب دیگری به نام Froala منتشر شد که هرچند نگارش‌های تجاری هم دارد، اما سورس آخرین نگارش آن برای عموم قابل دریافت است. در ادامه مروری خواهیم داشت بر نحوه‌ی یکپارچه سازی آن با ASP.NET MVC و همچنین ASP.NET Web forms.


دریافت آخرین نگارش Froala WYSIWYG Editor
برای دریافت فایل‌های آخرین نگارش این ادیتور وب می‌توانید به سایت آن، قسمت دریافت فایل‌ها مراجعه نمائید.
http://editor.froala.com/download
و یا به این آدرس مراجعه کنید:
https://github.com/froala/wysiwyg-editor/releases 


ساختار پروژه و نحوه‌ی کپی فایل‌های آن
در هر دو مثالی که فایل‌های آن‌را از انتهای بحث می‌توانید دریافت کنید، این ساختار رعایت شده است:


فایل‌های CSS و فونت‌های آن، در پوشه‌ی Content قرار گرفته‌اند.
فایل‌های اسکریپت و زبان آن (که دارای زبان فارسی هم هست) در پوشه‌ی Scripts کپی شده‌اند.

یک نکته
فایل font-awesome.css را نیاز است کمی اصلاح کنید. مسیر پوشه‌ی فونت‌های آن اکنون با fonts شروع می‌شود.


تنظیمات اولیه

تفاوتی نمی‌کند که از وب فرم‌ها استفاده می‌کنید یا MVC، نحوه‌ی تعریف و افزودن پیش نیازهای این ادیتور به نحو ذیل است:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>

    <link href="Content/font-awesome.css" rel="stylesheet" />
    <link href="Content/froala_editor.css" rel="stylesheet" />

    <script src="Scripts/jquery-1.10.2.min.js"></script>
    <script src="Scripts/froala_editor.min.js"></script>
    <script src="Scripts/langs/fa.js"></script>
</head>
<body>
    <form id="form1" runat="server">
    </form>
</body>
</html>
دو فایل CSS دارد (آیکن‌های آن و همچنین شیوه نامه‌ی اصلی ادیتور) به همراه سه فایل JS (جی‌کوئری، ادیتور و فایل زبان فارسی آن) که باید در فایل master یا layout سایت اضافه شوند.


استفاده از Froala WYSIWYG Editor در ASP.NET MVC

در ادامه نحوه‌ی فعال سازی ادیتور وب Froala را در یک View برنامه‌های ASP.NET MVC ملاحظه می‌کنید:
@{
    ViewBag.Title = "Index";
}

<style type="text/css">
    /*تنظیم فونت پیش فرض ادیتور*/
    .froala-element {
    }
</style>

@using (Html.BeginForm(actionName: "Index", controllerName: "Home"))
{
    @Html.TextArea(name: "Editor1")
    <input type="submit" value="ارسال" />
}

@section Scripts
{
    <script type="text/javascript">
        $(function () {
            $('#Editor1').editable({
                buttons: ["bold", "italic", "underline", "strikeThrough", "fontFamily",
                    "fontSize", "color", "formatBlock", "align", "insertOrderedList",
                    "insertUnorderedList", "outdent", "indent", "selectAll", "createLink",
                    "insertImage", "insertVideo", "undo", "redo", "html", "save", "inserthorizontalrule"],
                inlineMode: false,
                inverseSkin: true,
                preloaderSrc: '@Url.Content("~/Content/img/preloader.gif")',
                allowedImageTypes: ["jpeg", "jpg", "png"],
                height: 300,
                language: "fa",
                direction: "rtl",
                fontList: ["Tahoma, Geneva", "Arial, Helvetica", "Impact, Charcoal"],
                autosave: true,
                autosaveInterval: 2500,
                saveURL: '@Url.Action("FroalaAutoSave", "Home")',
                saveParams: { postId: "123" },
                spellcheck: true,
                plainPaste: true,
                imageButtons: ["removeImage", "replaceImage", "linkImage"],
                borderColor: '#00008b',
                imageUploadURL: '@Url.Action("FroalaUploadImage", "Home")',
                imageParams: { postId: "123" },
                enableScript: false
            });
        });
    </script>
}
اگر می‌خواهید فونت پیش فرض آن را تنظیم کنید، باید مطابق کدهای ابتدای فایل، ویژگی‌های froala-element را تغییر دهید.
سپس این ادیتور را بر روی المان TextArea قرار گرفته در صفحه، فعال می‌کنیم.
در قسمت مقادیر buttons، تمام حالات ممکن پیش بینی شده‌اند. هر کدام را که نیاز ندارید، حذف کنید.
نحوه‌ی تعریف زبان و راست به چپ بودن این ادیتور را با مقدار دهی پارامترهای language و direction ملاحظه می‌کنید.

پارامترهای autosave، saveURL و saveParams کار تنظیم ارسال خودکار محتوای ادیتور را جهت ذخیره‌ی آن در سرور به عهده دارند. بر اساس مقدار autosaveInterval می‌توان مشخص کرد که هر چند میلی ثانیه یکبار این‌کار باید انجام شود.
        /// <summary>
        /// ذخیره سازی خودکار
        /// </summary>
        [HttpPost]
        [ValidateInput(false)]
        public ActionResult FroalaAutoSave(string body, int? postId) // نام پارامتر بادی را تغییر ندهید
        {
            //todo: save body ...
            return new EmptyResult();
        }
در قسمت سمت سرور هم می‌توان این مقادیر ارسالی را در اکشن متدی که ملاحظه می‌کنید، دریافت کرد.
چون قرار است تگ‌های HTML به سرور ارسال شوند، ویژگی ValidateInput به false تنظیم شده‌است.
saveParams آن، برای مقدار دهی پارامترهای اضافی است که نیاز می‌باشند تا به سرور ارسال شوند. مثلا شماره مطلب جاری نیز به سرور ارسال گردد.
در اینجا نام پارامتری که ارسال می‌گردد، دقیقا مساوی body است. بنابراین آن‌را تغییر ندهید.

پارامترهای imageUploadURL و imageParams برای فعال سازی ذخیره تصاویر آن در سرور کاربرد دارند.
اکشن متد مدیریت کننده‌ی آن به نحو ذیل می‌تواند تعریف شود:
        // todo: مسایل امنیتی آپلود را فراموش نکنید
        /// <summary>
        /// ذخیره سازی تصاویر ارسالی
        /// </summary>
        [HttpPost]
        public ActionResult FroalaUploadImage(HttpPostedFileBase file, int? postId) // نام پارامتر فایل را تغییر ندهید
        {
            var fileName = Path.GetFileName(file.FileName);
            var rootPath = Server.MapPath("~/images/");
            file.SaveAs(Path.Combine(rootPath, fileName));
            return Json(new { link = "images/" + fileName }, JsonRequestBehavior.AllowGet);
        }
در اینجا نام پارامتری که به سرور ارسال می‌گردد، دقیقا معادل file است. بنابراین آن‌را تغییر ندهید.
خروجی آن برای مشخص سازی محل ذخیره سازی تصویر در سرور باید یک خروجی JSON دارای خاصیت و پارامتر link به نحو فوق باشد (این مسیر، یک مسیر نسبی است؛ نسبت به ریشه سایت).
imageParams آن برای مقدار دهی پارامترهای اضافی است که نیاز می‌باشند تا به سرور ارسال شوند. مثلا شماره مطلب جاری نیز به سرور ارسال گردد.


استفاده از Froala WYSIWYG Editor در ASP.NET Web forms
تمام نکاتی که در قسمت تنظیمات ASP.NET MVC در مورد ویژگی‌های سمت کلاینت این ادیتور ذکر شد، در مورد وب فرم‌ها نیز صادق است. فقط قسمت مدیریت سمت سرور آن اندکی تفاوت دارد.
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master"
    ValidateRequest="false"
    EnableEventValidation="false"
    AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="FroalaWebFormsTest.Default" %>

<%--اعتبارسنجی ورودی غیرفعال شده چون باید تگ ارسال شود--%>
<%--همچنین در وب کانفیگ هم تنظیم دیگری نیاز دارد--%>

<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <%--حالت کلاینت آی دی بهتر است تنظیم شود در اینجا--%>
    <asp:TextBox ID="txtEditor" ClientIDMode="Static"
        runat="server" Height="199px" TextMode="MultiLine" Width="447px"></asp:TextBox>
    <br />
    <asp:Button ID="btnSave" runat="server" OnClick="btnSave_Click" Text="ارسال" />

    <style type="text/css">
        /*تنظیم فونت پیش فرض ادیتور*/
        .froala-element {
        }
    </style>

    <script type="text/javascript">
        $(function () {
            $('#txtEditor').editable({
                buttons: ["bold", "italic", "underline", "strikeThrough", "fontFamily",
                    "fontSize", "color", "formatBlock", "align", "insertOrderedList",
                    "insertUnorderedList", "outdent", "indent", "selectAll", "createLink",
                    "insertImage", "insertVideo", "undo", "redo", "html", "save", "inserthorizontalrule"],
                inlineMode: false,
                inverseSkin: true,
                preloaderSrc: 'Content/img/preloader.gif',
                allowedImageTypes: ["jpeg", "jpg", "png"],
                height: 300,
                language: "fa",
                direction: "rtl",
                fontList: ["Tahoma, Geneva", "Arial, Helvetica", "Impact, Charcoal"],
                autosave: true,
                autosaveInterval: 2500,
                saveURL: 'FroalaHandler.ashx',
                saveParams: { postId: "123" },
                spellcheck: true,
                plainPaste: true,
                imageButtons: ["removeImage", "replaceImage", "linkImage"],
                borderColor: '#00008b',
                imageUploadURL: 'FroalaHandler.ashx',
                imageParams: { postId: "123" },
                enableScript: false
            });
        });
    </script>
</asp:Content>
همانطور که ملاحظه می‌کنید،  ValidateRequest صفحه به false تنظیم شده و همچنین در وب کانفیگ httpRuntime requestValidationMode به نگارش 2 تنظیم گردیده‌است تا بتوان توسط این ادیتور تگ‌های ارسالی را به سرور ارسال کرد.
به علاوه ClientIDMode=Static نیز تنظیم شده‌است، تا بتوان از ID تکست باکس قرار گرفته در صفحه، به سادگی در کدهای سمت کاربر جی‌کوئری استفاده کرد.
اگر دقت کرده باشید، save urlها اینبار به فایل FroalaHandler.ashx اشاره می‌کنند. محتوای این Genric handler را ذیل مشاهده می‌کنید:
using System.IO;
using System.Web;
using System.Web.Script.Serialization;

namespace FroalaWebFormsTest
{
    public class FroalaHandler : IHttpHandler
    {
        //todo: برای اینکارها بهتر است از وب ای پی آی استفاده شود
        //todo: یا دو هندلر مجزا یکی برای تصاویر و دیگری برای ذخیره سازی متن

        public void ProcessRequest(HttpContext context)
        {
            var body = context.Request.Form["body"];
            var postId = context.Request.Form["postId"];
            if (!string.IsNullOrWhiteSpace(body) && !string.IsNullOrWhiteSpace(postId))
            {
                //todo: save changes

                context.Response.ContentType = "text/plain";
                context.Response.Write("");
                context.Response.End();
            }

            var files = context.Request.Files;
            if (files.Keys.Count > 0)
            {
                foreach (string fileKey in files)
                {
                    var file = context.Request.Files[fileKey];
                    if (file == null || file.ContentLength == 0)
                        continue;

                    //todo: در اینجا مسایل امنیتی آپلود فراموش نشود
                    var fileName = Path.GetFileName(file.FileName);
                    var rootPath = context.Server.MapPath("~/images/");
                    file.SaveAs(Path.Combine(rootPath, fileName));


                    var json = new JavaScriptSerializer().Serialize(new { link = "images/" + fileName });
                    // البته اینجا یک فایل بیشتر ارسال نمی‌شود
                    context.Response.ContentType = "text/plain";
                    context.Response.Write(json);
                    context.Response.End();
                }
            }

            context.Response.ContentType = "text/plain";
            context.Response.Write("");
            context.Response.End();
        }

        public bool IsReusable
        {
            get { return false; }
        }
    }
}
در اینجا نحوه‌ی مدیریت سمت سرور auto save و همچنین ارسال تصاویر ادیتور Froala ، ذکر شده‌اند. با استفاده از context.Request.Form می‌توان به عناصر ارسالی به سرور دسترسی پیدا کرد. همچنین توسط context.Request.Files، اگر فایلی ارسال شده بود، ذخیره شده و نهایتا خروجی JSON مدنظر بازگشت داده می‌شود.


یک نکته‌ی امنیتی مهم
<location path="upload">
  <system.webServer>
    <handlers accessPolicy="Read" />
  </system.webServer>
</location>
تنظیم فوق را در web.config سایت، جهت Read only کردن پوشه‌ی ارسال تصاویر، حتما مدنظر داشته باشید. در اینجا فرض شده‌است که پوشه‌ی uploads قرار است قابلیت اجرای فایل‌های پویا را نداشته باشد.


کدهای کامل این مطلب را در ادامه می‌توانید دریافت کنید
Froala-Sample
 
نظرات مطالب
اعمال صفحه بندی به کمک OFFSET و FETCH در SQL Server 2012
سلام  
دوست عزیز، مثالی که برای شما زده شد، امکان سورت دلخواه را فراهم می‌کند، شما می‌توانید، هر کدام را به دلخواه نزولی یا صعودی نمایید، محدودیتی ندارد، برای مطالعه بیشتر می‌توانید به آدرس زیر مراجعه نمایید:
یادآور شوم،چنانچه Performance برای شما اهمیت دارد، بهتر است از Case در Order by استفاده ننمایید، و بهتر است در زمان Run Time از طریق کد نویسی سمت سرور، Script خود را Generate نمایید، به عنوان مثال
SELECT BusinessEntityID, FirstName, LastName
FROM Testoffset
ORDER BY BusinessEntityID Desc,Firstname ASC
OFFSET 3 ROWS
FETCH First 3 ROWS only
موفق باشید.
بازخوردهای پروژه‌ها
دیت پیکر فارسی
مسلما یکی از مشکلات ما در زبان فارسی تقویم هست و بیشترین کامپوننت‌ها در تمامی سیستم‌های دیجیتال موبایل، کامپیوتر برنامه نویسی دیتابیس و غیره تبدیل تاریخ هست
  تلاشهای همه افراد هم خوب و ستودنی است ولی به نظر خود من این دیت پیکر امکانات کمی داره
دیت پیکر
http://stefangabos.ro/jquery/zebra-datepicker/

خیلی عالی هست و با کتابخانه PersianCalendar که در جاوا اسکریپت نوشته شده به سادگی فارسی میشه و خیلی خوب هم کار میکنه حالا باید این نسخه ای که تاریخ فارسی داره رو بذارم روی وب
تبدیلش به کامپوننت هم کار زیاد سختی نیست
مطالب
نمایش ساختارهای درختی توسط jqGrid
jqGrid از نمایش دو ساختار درختی Nested Set model و Adjacency model پشتیبانی می‌کند. توضیحات تکمیلی و پایه‌ای را در مورد این دو روش مدل سازی اطلاعات، در مطلب «SQL Antipattern #2» می‌توانید مطالعه کنید.
در اینجا روش Adjacency model را به علت بیشتر مرسوم بودن آن و شباهت بسیار زیاد آن به «مدل‌های خود ارجاع دهنده» بررسی خواهیم کرد.


مدل داده‌ای Adjacency

در حالت ساختار درختی از نوع مجاورت، علاوه بر خواص اصلی یک کلاس، سه خاصیت دیگر نیز باید تعریف شوند:
using System;

namespace jqGrid13.Models
{
    public class BlogComment
    {
        // Other properties 
        public int Id { set; get; }
        public string Body { set; get; }
        public DateTime AddDateTime { set; get; }

        // for treeGridModel: 'adjacency'
        public int? ParentId { get; set; }
        public bool IsNotExpandable { get; set; }
        public bool IsExpanded { get; set; }
    }
}
ParentId که سبب تولید یک مدل خود ارجاع دهنده می‌شود.
IsNotExpandable به این معنا است که نود جاری آیا قرار است باز شود و فرزندی دارد یا خیر؟ اگر فرزندی ندارد باید مساوی True قرار گیرد.
IsExpanded حالت پیش فرض باز بودن یا نبودن یک نود را مشخص می‌کند.


نحوه‌ی بازگشت اطلاعات درختی از سمت سرور

در نگارش فعلی jqGrid، در حالت نمایش درختی، مباحث صفحه بندی و مرتب سازی غیرفعال هستند و کدهای مرتبط با آن که در اینجا ذکر شده‌اند، فعلا تاثیری ندارند (البته با کمی تغییر در کدهای آن، می‌توان این قابلیت را هم فعال کرد. اطلاعات بیشتر).
نکته‌ی مهم treeGrid، سه پارامتر دیگر هستند که از سمت کلاینت به سرور ارسال می‌شوند:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web.Mvc;
using jqGrid13.Models;
using JqGridHelper.DynamicSearch; // for dynamic OrderBy
using JqGridHelper.Models;
using JqGridHelper.Utils;

namespace jqGrid13.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult GetComments(JqGridRequest request, int? nodeid, int? parentid, int? n_level)
        {
            var list = BlogCommentsDataSource.LatestBlogComments;

            // در این حالت خاص فعلا در نگارش جای جی‌کیو‌گرید صفحه بندی کار نمی‌کند و فعال نیست و محاسبات ذیل اهمیتی ندارند
            var pageIndex = request.page - 1;
            var pageSize = request.rows;
            var totalRecords = list.Count;
            var totalPages = (int)Math.Ceiling(totalRecords / (float)pageSize);

            var productsQuery = list.AsQueryable();
            
            if (nodeid == null)
            {
                productsQuery = productsQuery.Where(x => x.ParentId == null);
            }
            else
            {
                productsQuery = productsQuery.Where(x => x.ParentId == nodeid.Value);
            }

            var products = productsQuery.OrderBy(request.sidx + " " + request.sord)
                                        .Skip(pageIndex * pageSize)
                                        .Take(pageSize)
                                        .ToList();


            var newLevel = n_level == null ? 0 : n_level.Value + 1;
            var productsData = new JqGridData
            {
                Total = totalPages,
                Page = request.page,
                Records = totalRecords,
                Rows = (products.Select(comment => new JqGridRowData
                {
                    Id = comment.Id,
                    RowCells = new List<object> 
                               {
                                   comment.Id,
                                   comment.Body,
                                   comment.AddDateTime.ToPersianDate(),
                                   // اطلاعات خاص نمایش درختی به ترتیب
           newLevel,
           comment.ParentId == null ? "" : comment.ParentId.Value.ToString(CultureInfo.InvariantCulture),
           comment.IsNotExpandable,
           comment.IsExpanded
                               }
                })).ToList()
            };
            return Json(productsData, JsonRequestBehavior.AllowGet);
        }
    }
}
nodeid اگر نال بود، یعنی کل اطلاعات ریشه‌ها (مواردی که parentId مساوی نال دارند)، باید واکشی شوند. اگر nodeid مقدار داشت، یعنی فرزند نود جاری قرار است بازگشت داده شود.
n_level مقدار جلو رفتگی نمایش اطلاعات یک نود را مشخص می‌کند. در اینجا چون با کلیک بر روی هر نود، فرزند آن از سرور واکشی می‌شود و lazy loading برقرار است، بازگشت مقدار n_level دریافتی از کلاینت به علاوه یک، کافی است. اگر نیاز است تمام نودها باز شده نمایش داده شوند، این مورد را باید به صورت دستی محاسبه کرده و در مدل BlogComment پیش بینی کنید.
در نهایت آرایه‌ای از خواص مدنظر به همراه 4 خاصیت ساختار درختی باید به ترتیب بازگشت داده شوند.




فعال سازی سمت کاربر treeGrid

برای فعال سازی سمت کاربر نمایش درختی اطلاعات، باید سه خاصیت ذیل تنظیم شوند:
            $('#list').jqGrid({
                caption: "آزمایش سیزدهم",
                // .... مانند قبل
                treeGrid: true,
                treeGridModel: 'adjacency',
                ExpandColumn: '@(StronglyTyped.PropertyName<BlogComment>(x => x.Body))'
            }).jqGrid('gridResize', { minWidth: 400 });
        });
تنظیم treeGrid: true سبب فعال سازی treeGrid می‌شود. توسط treeGridModel حالات Nested Set model و Adjacency model قابل تنظیم هستند و ExpandColumn نام ستونی را مشخص می‌کند که قرار است فرزندان آن نمایش داده شوند.


یک نکته‌ی تکمیلی

اگر می‌خواهید دقیقا به شکل زیر برسید:

تنظیم rownumbers: true گرید را حذف کنید. همچنین ستون Id را نیز با تنظیم‌های hidden:true, key: true مخفی نمائید (در تعاریف colModel).


کدهای کامل این مثال را از اینجا می‌توانید دریافت کنید
jqGrid13.zip


برای مطالعه بیشتر
Tree Grid
Nested Set Model
Adjacency Model
اشتراک‌ها
وب اپلیکیشن پیش‌ رونده (PWA)

یکی از مهترین ترندهای این روزها وب اپلیکیشن‌های پیش رونده یا PWA هست. به طور خلاصه PWA این امکان رو برای ما فراهم میکنه تا ویژگی‌های یک اپلیکیشن Native رو با وب سایت خودمون ترکیب کنیم تا تجربه‌ی بی‌نظیر و یکپارچه‌ای رو در اختیار کاربر قرار بدیم. 

وب اپلیکیشن پیش‌ رونده (PWA)
اشتراک‌ها
چرا وب اپ های پراگرسیو آینده وب سایت های ایرانی است؟

وب اپ‌های پراگرسیو Progressive Web Apps از قابلیت‌های وبِ مدرن استفاده می‌کند تا یک تجربه اپ(موبایل)مانندی را برای کاربر فراهم کند . PWA ها آخرین ترند توسعه اپ موبایل با استفاده از تکنولوژی‌های وب است. که هم اکنون (در زمان نوشتن این نوشته) فقط روی دستگاه‌های اندرویدی پشتیبانی می‌شوند. 

چرا وب اپ های پراگرسیو آینده وب سایت های ایرانی است؟
مطالب
پنج دلیل برای توسعه‌ی وب با ASP.NET Core

یک:  ASP.NET Core مستقل از Platform است

آینده‌ی محتوم نرم‌افزار، توسعه به شیوه‌های مستقل از Platform است. شاید این دلیل به تنهایی برای مهاجرت به ASP.NET Core کافی باشد. امروزه نرم‌افزارهایی که مبتنی بر یک Platform خاص نیستند، نسبت به سایر نرم‌افزارها مزیت رقابتی‌تری دارند. نرم‌افزارهای Cross Platform یا مستقل از Platform، بر روی هر سیستم عاملی اجرا می‌شوند. برای اجرای آنها در کامپیوترهای شخصی یا Server کافیست معماری پردازنده‌ی مرکزی x86 باشد و سیستم عامل نیز یکی از انواع ویندوز، لینوکس یا مک.
دلیل مستقل بودن ASP.NET Core از Platform، مبتنی بودن آن بر NET Core. است. این نسخه از دات‌نت را می‌توان برای سیستم‌‌عامل‌های مختلف از http://dot.net دانلود و نصب کرد.
برای اجرای نرم‌افزارهایی که مبتنی بر NET Core. هستند نیاز به بازنویسی کدها یا استفاده از زبان‌های برنامه‌نویسی جداگانه‌ای نیست. این خاصیت همچنین برای libraryهای استانداردی که از این نسخه از دات‌نت استفاده می‌کنند نیز صادق است.

دو:  Open Source است

یکی از انتقادهایی که سال‌ها به مایکروسافت می‌شد، ناشناخته بودن سورس نرم‌افزارهای این شرکت و انحصار طلبی‌هایش بود. اما در سال‌های اخیر مایکروسافت نشان داده‌است که این جنبه از کاراکترش را به تدریج اصلاح کرده‌است. به طوری که اسکات هانسلمن، یکی از کارمندان این شرکت و وبلاگ‌نویس مشهور در این مورد گفته است:
دلیل آمدن من به مایکروسافت این بود که می‌خواستیم هر چقدر می‌توانیم کارها را Open Source کنیم و یک جامعه‌ی کاربری برای دات‌نت و اوپن سورس بسازیم و حالا به NET Core 1.0. رسیده‌ایم.
زمانی شایعه‌ی لو رفتن بخشی از سورس کد ویندوز ۹۵، در صدر اخبار تکنولوژی بود و این یک شکست برای مایکروسافت محسوب می‌شد. اما امروزه ASP.NET Core با لایسنس MIT عرضه شده است که یکی از آزادترین مجوزهای اوپن سورس است. نرم‌افزارهایی که با این مجوز عرضه می‌شوند، آزادی تغییر کد، ادغام با مجوزهای دیگر، عرضه به عنوان محصول دیگر، استفاده تجاری و ... را به همه‌ی توسعه‌دهندگان می‌دهد.

سه: جدا بودن از Web Server

این نسخه‌ی از APS.NET، کاملاً از وب‌سرور که نرم‌افزارها را هاست می‌کند، جدا (decouple) شده است. اگرچه همچنان استفاده از IIS بر روی ویندوز منطقی به نظر می‌رسد اما مایکروسافت یک پروژه‌ی اوپن سورس دیگری را به نام Kestrel نیز منتشر کرده است.
وب‌سرور Kestrel مبتنی بر پروژه libuv است و libuv در اصل برای هاست کردن Node.js تولید شده بود و تأکید آن بر روی انجام عملیات I/O به صورت asynchronous است.
نکته جالب این است که یک برنامه‌ی مبتنی بر ASP.NET Core، در واقع یک Console Application است که در متد Main آن وب‌سرور فراخوانی می‌شود:
using System;
using Microsoft.AspNetCore.Hosting;
namespace aspnetcoreapp
{
public class Program
{
  public static void Main(string[] args)
  {
   var host = new WebHostBuilder()
                  .UseKestrel()
                  .UseStartup<Startup>()
                  .Build();
   host.Run();
  }
}
}

چهار: تزریق وابستگی (Dependency Injection) تو کار

تزریق وابستگی‌ها برای ایجاد وابستگی سست (loosely coupling) بین اشیاء مرتبط و وابسته به یکدیگر است. به جای نمونه‌سازی مستقیم اشیاء مرتبط، یا استفاده از ارجاع‌های ایستا به آن اشیاء، زمانی که یک کلاس به آنها احتیاج داشته باشد، با روش‌های خاصی از طریق DI به اشیاء مورد نیاز دسترسی پیدا می‌کند. در این استراتژی، ماژول‌های سطح بالا نباید به ماژول‌های سطح پایین وابسته باشند، بلکه هر دو باید به abstraction (معمولا Interface ها) وابسته باشند.
وقتی یک سیستم برای استفاده‌ی از DI طراحی شده‌است و کلاس‌های زیادی دارد که وابستگی‌هایش را از طریق constructor یا property‌ها درخواست می‌کند، بهتر است یک کلاس مخصوص ایجاد آن کلاس‌ها و وابستگی‌هایشان داشته باشد. به این کلاس‌ها container، یا Inversion of Control (IoC) container یا Dependency Injection (DI) container گفته می‌شود.
با این روش، بدون نیاز به hard code کردن instance سازی از کلاس‌ها، می‌توان گراف‌های پیچیده وابستگی را در اختیار یک کلاس قرار داد.
طراحی ASP.NET Core از پایه طوری است که حداکثر استفاده را از Dependency Injection می‌کند. یک container ساده توکار با نام IServiceProvider وجود دارد که به صورت پیش‌فرض constructor injection را پشتیبانی می‌کند.
در ASP.NET Core با مفهومی به نام service سر و کار خواهید داشت که در واقع به type هایی گفته می‌شود که از طریق DI در اختیار شما قرار می‌گیرند. سرویس‌ها در متد ConfigureServices کلاس Startup برنامه شما تعریف می‌شوند. این service‌ها می‌توانند Entity Framework Core یا ASP.NET Core MVC باشند یا سرویس‌هایی که توسط شما تعریف شده‌اند. مثال:
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices (IServiceCollection services)
{
// Add framework services.
services.AddDbContext<ApplicationDbContext>(options =>
  options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
  .AddEntityFrameworkStores<ApplicationDbContext>()
  .AddDefaultTokenProviders();
services.AddMvc();
// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();
}


پنج: یکپارچگی با framework‌های مدرن سمت کلاینت

فرآیند build در برنامه‌های تحت وب مدرن معمولاً این وظایف را انجام می‌دهد:
  • bundle و minify کردن فایل‌های جاوا اسکریپت و همینطور CSS
  • اجرای ابزارهایی برای bundle و minify کردن قبل از هر build
  • کامپایل کردن فایل‌های LESS و SASS در CSS
  • کامپیال کردن فایل‌های CoffeeScript و TypeScript در JavaScript
برای اجرای چنین فرآیندهایی از ابزاری به نام task runner استفاده می‌شود که Visual Studio از دو ابزار task runner مبتنی برا جاوا اسکریپت به نام‌های Gulp و Grunt بهره می‌برد. از این ابزارها با استفاده از ASP.NET Core Web Application template می‌توان در ASP.NET Core استفاده کرد.
همچنین امکان استفاده از Bower که یک package manager (مانند NuGet) برای وب است، وجود دارد. معمولاً از Bower برای نصب فایل‌های CSS ، فونت‌ها، framework‌های سمت کلاینت و کتابخانه‌های جاوا اسکریپت استفاده می‌شود. اگرچه بسیاری از package‌ها در NuGet هم وجود دارند، اما تمرکز بیشتر NuGet بر روی کتابخانه‌های دات‌نتی است.
نصب و استفاده‌ی سایر library‌های سمت کلاینت مانند Bootstrap ، Knockout.js ، Angular JS  و زبان TypeScript نیز در Visual Studio و هماهنگی آن با ASP.NET Core نیز بسیار ساده است.
پس همین حالا دست به کار شوید و با نصب -حداقل - Microsoft Visual Studio 2015 Update 3 بر روی ویندوز یا Visual Studio Code  بر روی هر سیستم عاملی از برنامه‌نویسی با ASP.NET Core لذت ببرید!
منابع :
مطالب
Pro Agile .NET Development With Scrum - قسمت اول
 با همکاری آقایان سید مجتبی حسینی و محمد شریفی طی یک سری مقالات سریالی قصد داریم ترجمه آزادی از کتاب  Pro Agile .NET Development With Scrum نوشته Jerrel Blankenship  و Matthew Bussa ، داشته باشیم. 
با توجه به اینکه در سایت جاری مطالب قسمت اول کتاب پوشش داده شده است، ما هم دوباره کاری نکرده و میتوانید از این مقاله استفاده کنید.

مدیریت پروژه‌های چابک با اسکرام
در این فصل با روشها و ماهیت تکرارپذیر اسکرام آشنا می‌شوید که استخوان‌بندی فرآیندی را تعریف می‌کند که دربردارندۀ  مجموعه‌ای از نقشها و فعالیتهایی است که همگی بر پشتیبانی از تیم مسؤول تولید محصول، تمرکز می‌کنند. 
مطالعۀ موردی بخش دوم این کتاب از شیوۀ اسکرام به نحوی پیروی می‌کند که قادر به دیدن اجرایی عملی از تمام ویژگیهای کلیدی‌ای که در این فصل از آنها بحث می‌شود، خواهید بود و به شما کمک می‌کند تا مزیت‌های این شیوه را به خوبی درک کنید.
اسکرام چیست؟
اسکرام رویکردی تکرارپذیر جهت توسعۀ نرم‌افزار است که بصورت تنگاتنگی با اصول و بیانیۀ چابک هم‌سو شده است. اسکرام از دنباله‌ای از بلاکهای زمانی به نام اسپرینت ساخته شده است که بر ارائۀ محصولات کارآمد تمرکز می‌کند. یک اسپرینت نوعاً از دو تا چهار هفته به طول می‌انجامد و با هدف یا موضوعی که واضح کنندۀ اسپرینت است، تعریف شده است.
اسپرینتها نسبت به تغییرات ایزوله شده‌اند و بدون هیچ اختلالی، تیم توسعه را بر ارائۀ محصولی کارآمد، متمرکز می‌سازند. کارها در Product   Backlog ( لیستی از کارهای کلی یک پروژه است که باید آن را بر اساس درجه اهمیت، دسته بندی نمود) اولویت‌بندی شده که توسط صاحب محصول مدیریت می‌شود. قبل از وقوع هر اسپرینت، یک ویژگی از Product Backlog  انتخاب شده و تیم توافق می‌کند که در انتهای آن اسپرینت، آن ویژگی را ارائه کند.
برای آنکه همه چیز بخوبی پیش برود، یک نفر به عنوان ScrumMaster (که وظیفه نگهداری و حفظ فرآیند را برعهده دارد) تعیین می‌شود تا اطمینان حاصل شود که هیچ مانعی باعث جلوگیری از ارائۀ ویژگیهایی که تیم توسعه مد نظر قرار داده، نشود. جلسات سرپایی روزانه به تیم کمک می‌کند تا دربارۀ هر مشکلی که مانع کار است، گفتگو کنند. مرور هر اسپرینت در انتهای آن به ارتقای فرآیند کمک می‌کند.
شکل 1-2 نمایش گرافیکی روش اسکرام است که حاوی همۀ نقشها و فعالیتها و خروجیهای اسکرام بوده که در ادامه، بیشتر دربارۀ آنها خواهید خواند. 
 




  شیوه‌های برنامه محور در مقابل شیوه‌های ارزش محور
هنگام ملاحظۀ تفاوت میان شیوۀ آبشاری و شیوۀ چابک، نیاز است تا به هستۀ مرکزی هر روش نگریست. یکی از شیوه‌ها از نقشه‌ای برگرفته شده که در ابتدای پروژه ایجاد شده است و شیوۀ دیگر از ارزشی برگرفته شده که شما به مشتری می‌دهید.

شیوۀ آبشاری (برنامه محور)
به شیوۀ آبشاری می‌توان به منزلۀ شیوه‌ای برنامه محور در توسعۀ نرم‌افزار نگریست. در گذشته، این شیوۀ توسعه بسیار مورد استفاده بود، نه به این دلیل که بهترین شیوۀ توسعۀ نرم‌افزار بود، بلکه به این دلیل که تنها شیوۀ شناخته شده بود.
پروژه‌ای که شیوۀ آبشاری را به کار می‌برد با ریسک بسیار بالایی مواجه بود؛ به این دلیل که همه چیز در ابتدای پروژه طرح‌ریزی می‌شد. تمام نیازمندیها و جستجوها و تعیین بازۀ کاری قبل از آنکه حتی یک خط کد نوشته شود، جمع‌آوری می‌شد. مشتریان باید همۀ آنچه را که از سیستم انتظار داشتند، در ابتدای امر می‌دانستند. در زمانی که مشتریان دقیقاً نمی‌دانستند که چه می‌خواهند اما باید تمام جزئیات نیازهای خود را تعریف می‌کردند و در یک وهله باید جزئیات کار را تعیین می‌کردند و تا آخر نیز نمی‌توانستند آن را تغییر دهند؛ حتی اگر بعداً متوجه می‌شدند که نیازشان تغییر کرده است.
این رویکرد سرانجام پروژه را، حتی قبل از آنکه شروع شود، با شکست مواجه می‌کرد. کل فرآیند به سمت مشکلاتی هدایت می‌شد که تا پایان پروژه نیز پنهان می‌ماندند. زیرا مشتری همۀ نکات جزئی کار را مدنظر قرار نداده بود و راهی برای تغییرات مورد نیاز وجود نداشت. گاهی انجام تغییر مستلزم هزینۀ بسیار بالایی بود. در این گونه پروژه‌ها دامنۀ پروژه دچار تغییرات می‌شد؛  توسعه‌دهنده از مسائلی که مشتری درصدد حل آنها بود سردرنمی‌آورد و به همین ترتیب مشتری.
توسعۀ برنامه محور به مانند روند پرش حلقه‌ای است: شما ابتدا جستجو می‌کنید و یک مرتبه از میان آن حلقه پریده و وارد حلقۀ جمع‌آوری نیازمندیها می‌شوید و از آنجا وارد حلقۀ طراحی می‌شوید. از یک حلقه نمی‌توانید عبور کنید مگر اینکه از حلقۀ پیشین آن پریده باشید و با یک مرتبه، عبور از یک حلقه برگشتن به آن حلقه ممکن نیست. حتی اگر نیاز باشد چنین کاری انجام شود. ممکن نیست که اندکی از هر کاری را انجام داده و برای اطمینان از مسیر درست، قدری متوقف بمانید. فرآیند آبشاری فراهم کنندۀ بستری نیست که در آن توسعه دهند بتواند به مشتری خود بگوید: «مایل هستم که کاری را که تاکنون انجام داده‌ام، به شما نشان دهم تا ببینید که آیا با آنچه شما می‌خواهید منطبق است یا خیر».
معمولاً در انتهای پروژه است که مشکلات بزرگی بروز پیدا می‌کنند که نسبتاً خیلی دیر است. این مورد منجر به آن می‌شود که چند تیم به کار وارد شده و افراد بیشتری در پروژه استفاده شوند؛ به این امید که پروژه سریعتر به اتمام برسد و البته چنین نتیجه‌ای به ندرت اتفاق می‌افتد. در نتیجه بخشهایی از پروژه باید کنار گذاشته شوند؛ یعنی یا حدود پروژه محدودتر شود، یا آزمودن آن حذف شود یا هردو.

شیوۀ اسکرام (ارزش محور)
اسکرام به عنوان شیوه‌ای ارزش محور در توسعۀ نرم‌افزار مورد توجه قرار می‌گیرد. اسکرام به چند دلیل تغییر چشم‌گیری نسبت به شیوۀ آبشاری داشته‌است.  اسکرام به جای آنکه در ابتدا به جمع‌آوری نیازمندیهای مورد نیاز برای هر ویژگی مد نظر پروژه بپردازد و به جای آنکه همۀ طراحی‌های خود را مبتنی بر این نیازمندیها کامل کرده و سپس به کدنویسی برنامه مبتنی بر این طرحهای از اول مشخص شده بپردازد؛ به توسعۀ تکرارپذیر و افزایشی می‌نگرد.
اسکرام تماماً معطوف به مسیرهایی جزئی در حل مسأله و ارزیابی مجدد آن مسأله پس از طی هر مسیر است.
  • بلاکهای جزئی با عنوان اسپرینت
  • ویژگیهای جزئی
  • تیم‌های کوچک
بلاکهای زمانی کوچک بیانگر چگونگی کار بر روی حل مسأله توسط تیم توسعه است. به هر اسپرینت می‌توان به صورت یک پروژۀ آبشاری کوچک نگریست. زیرا در هر اسپرینت شما همۀ کارهایی را که به طور عادی در یک پروژۀ آبشاری انجام می‌دهید، اجرا می‌کنید با این تفاوت که فقط در مقیاسی کوچک‌تر آن را انجام می‌دهید. در هر اسپرینت، شما یک ویژگی را انتخاب کرده و نیازمندیهای آن ویژگی را جمع‌آوری کرده و به طراحی آن ویژگی مبتنی بر نیازمندیهای به دست‌آمده پرداخته و سپس کدنویسی کرده و آن خصیصه را با توجه به طراحی صورت گرفته، تست می‌کنید. شما در اسکرام برخلاف روش آبشاری، تلاش نمی‌کنید که همه چیز را پیشاپیش طراحی کنید. بلکه شما چیزی را انجام می‌دهید که نیاز است انجام شود. هدف هر اسپرینت انجام ارتقایی (افزایشی) برای رسیدن به پروژۀ نهایی است؛ اما افزایشی که به طور بالقوه قابل ارائه است.
حال چگونه می‌توان در هر اسپرینت تعداد زیادی پروژه‌های آبشاری را انجام داد، در حالی که قبلاً به سختی یک پروژۀ آبشاری قابل انجام بود؟ جواب، انجام اسپرینتهایی با ویژگیهای کوچک است. ویژگیهای جزئی‌، قطعاتی از پروژه هستند که تلاش می‌کنند مسألۀ خاصی را برای مشتری حل کنند. آنها درصدد این نیستند که کل برنامه را ایجاد کنند. ویژگیهای مدنظر یک پروژه به تکه‌های کوچکتری شکسته می‌شوند که هنوز قادر به تامین ارزش برای مشتری بوده و می‌توان آنها را به سرعت انجام داد. با هرچه بیشتر شدن این ویژگیهای کامل شده در پروژه، مشتری کم کم با نمای کامل برنامه مورد نظر مواجه شده و آن را ملاحظه می‌کند.
همه‌ی این موارد توسط یک تیم کوچکی از توسعه‌دهندگان، تست‌کننده‌ها و طراحانی که صرفاً به انجام پروژه مشغول هستند، انجام می‌شود. این تیم، یک تیم با قابلیت‌هایی چندگانه است که هر عضو آن با انجام تمام کارهای تیم آشناست. هر عضوی از آن ممکن است که در همه چیز بهترین نباشد؛ اما هرکس می‌داند که چگونه یک کار ضروری را برای تکمیل پروژه انجام دهد. نگریستن به آنها به عنوان یک تیم SEAL  که هر عضو آن می‌داند که چگونه هرچیز مورد نیاز را انجام دهد، اما برای هرکاری کارشناسان مخصوص آن کار وجود دارد.
با انجام این کار در سطوح جزئی، مسائل این سطوح جزئی تا حدی شبیه مسائلی هستند که در انتهای پروژه در شیوۀ آبشاری رخ می‌دهند. در واقع اسکرام به گونه‌ای کار می‌کند که بتواند تا آنجا که ممکن است سریعاً مشکلات و مسائل را نشان دهد. مشکلات قابل پنهان شدن نیستند؛ چراکه پروژه به سطوحی کوچک و قابل مدیریت، تجزیه شده است. هنگامیکه مشکلی بروز پیدا می‌کند، تا وقت پیدا شدن راه حل و حل شدن آن، موجبات دردسر تیم را فراهم می‌کند و آنها نمی‌توانند از مسأله چشم‌پوشی کنند، چون برای همه قابل رؤیت است.
نکتۀ بسیارمهمی را باید دربارۀ اسکرام فهمید و آن اینکه اسکرام مشکلات را هرچه زودتر، به تیم نشان می‌دهد؛ اما آنها را حل نمی‌کند. 
اسکرام نه تنها ویژگیهایی را برای نمایش به مشتری توسط تیمهای فروش و بازاریابی تولید می‌کند، بلکه راه‌حلهایی را نیز به مشتری ارائه می‌دهد. چنین امری با اولویت‌بندی خصوصیت‌ها مطابق نیاز و خواسته‌های مشتری، صورت می‌گیرد. اگر مشتری‌ای تصور کند که ویژگی A باید از ویژگی B بسیار مهم‌تر باشد و توسعه دهنده، وقت زیادی را بر سر ویژگی B قبل از ویژگی A صرف کند، نمی‌تواند به نیاز مشتری به نحو مطلوبی، پاسخ‌گو باشد.

عوامل ثابت در مقابل عوامل متغیر
سه عامل یا قید کلیدی، برای هر پروژۀ نرم‌افزاری وجود دارند: زمان، منابع و محدودۀ پروژه. متأسفانه در یک زمان، هر سه عامل قابل جمع نیست. طبق شکل مثلثی زیر، در هر زمان می‌توان بر روی تاثیرات دو عامل کار کرد و آن دو عامل  اتفاقی را که رخ می‌دهد، بر سومی دیکته می‌کنند.



در مدل توسعۀ برنامه محور، حیطه و منابع پروژه، معمولاً عوامل ثابتند و زمان عامل متغیر است. در این حالت حیطۀ پروژه بر منابع و زمان حاکم است. این حالت تا زمانی خوب است که شما در میانۀ پروژه قراردارید. اما به مرور، رشد حیطۀ پروژه، چهره نامطلوب کار را نمایان می‌سازد. در این هنگام محدودۀ پروژه، گسترش خواهد یافت در حالی که نه منابع و نه زمان، متناسب با چنین تغییری، قابل تغییر نیستند. در این هنگام شما افراد بیشتری را به پروژه وارد می‌کنید، به این امید که به نتیجۀ مناسبی در انتهای کار دست یابید.
در مدل توسعۀ ارزش محور، منابع و زمان در مثلث ثابتند. شما از ابعاد تیمتان و سرعت انجام کارشان در اسپرینتهای قبلی آگاهید. در این حالت محدودۀ پروژه در مثلث فوق، عنصر متغیر می‌شود. به عبارت دیگر منابع پروژه و زمان، تعیین‌کنندۀ محدودۀ پروژه هستند.

محصولات اسکرام
اسکرام سه خروجی دارد:
  1.  product backlog : مجموعه‌ای اولویت بندی شده از نیازمندی‌های سطح بالای سیستمی که در نهایت بایستی تحویل داده شود.
  2. sprint backlog : مواردی از  product backlog که قرار است در یک sprint انجام شوند.
  3. نمودار burn-down :هدف نمودار burn-down، نمایش روند پیشرفت پروژه به صورت نموداری به اعضای تیم توسعه است که حاوی اطلاعاتی دربارۀ کل زمان انجام کار، زمان تخمین‌زده شده، مقدار کارانجام شده و عقب‌ماندگی‌های پروژه است.
این خروجی‌ها، محصولات فعالیت‌های اسکرام هستند و به تیم در جهت‌یابی و شفافیت کار کمک می‌کنند. افزون بر این خروجی‌های اصلی خروجی‌های فرعی‌ای نیز از قبیل معیار پذیرش (الزاماتی که باید در حل یک مسأله برآورده شود تا بتوان آن را کامل شده تلقی کرد) وجود دارد.

Product Backlog
product backlog لیستی از همه کارهای باقی‌مانده در یک پروژه است که باید انجام شوند. این لیست نمایانگر نیازمندیها و خواسته‌های مشتری است. در قلب این لیست «داستان کاربر (user story)» یعنی مؤلفۀ کلیدی اسکرام قرار دارد. این مؤلفه تعیین‌کنندۀ ملاک افزایش ارزش در نزد مشتری بوده و آن چیزی است که توسعه دهنده تلاش می‌کند، ارائه نماید و توسط صاحب محصول (product owner) (یعنی کسی که نسبت به افزودن یا حذف داستان کاربر (user story)‌ها به لیست، پاسخ‌گو است) مدیریت می‌شود. product backlog به طور دائم توسط صاحب محصول و مشتری اولویت‌بندی می‌شود. این اولویت‌بندی دائمی امری کلیدی برای اسکرام است. این امر تضمین می‌کند که داستان کاربر (user story) که تعیین‌کنندۀ بیشترین ارزش برای مشتریست، در صدر product backlog قرار گرفته باشد. با افزوده شدن یک داستان کاربر (user story) این مورد با سایر داستان‌های کاربر (user storyهای) پیشین مقایسه شده تا مشخص شود که در چه سطح ارزشی‌ای از نظر مشتری قراردارد. در طول یک اسپرینت، داستان کاربر (user storyها) را می‌توان به اسپرینت اضافه کرد. اما تا کامل شدن اسپرینت جاری، به تیم توسعه نشان داده نمی‌شود.

User Stories
همانطور که خاطرنشان شد، product backlog چیزی بیش از یک لیست اولویت‌بندی شده از داستان‌های کاربر (user storyها) نیست. یک داستان کاربر (user story)، یک کارت است که ارزش اضافه‌ای را برای مشتری توصیف می‌کند. داستان کاربر (user story) برای توسعه‌دهنده به منظور بیان ارزشی اضافه نوشته می‌شود. نکتۀ کلیدی یک داستان کاربر (user story) خوب، این است که داستان کاربر (user story) بخشی عمودی از لیست است و بخش افقی ویژگی‌ای است که فقط به یک سطح، مانند سطح بانک اطلاعات یا سطح رابط کاربری اثر می‌گذارد. به عبارت دیگر قطعۀ عمودی تمام سطوح را آن گونه که در شکل 3-2 نشان داده شده، متاثر می‌سازد. این کوچکترین مقدار کاری است که تمام سطوح یک محصول را تحت تاثیر قرارداده و برای مشتری ارزش ایجاد می‌کند. با نوشتن داستان‌های کاربر (user storyها) به گونه‌ای که در بخشهای عمودی جایز است، می‌توان قابلیت پایه‌ای را در اولین داستان کاربر (user story) ایجاد کرده و سپس به سادگی قابلیتی به این ویژگی به عنوان نیازهای مشتری اضافه کرد.


یک شیوۀ اطمینان از اینکه داستان کاربر (user story) فایدۀ قطعۀ عمودی بودن در یک سیستم را داراست این است که مطمئن شویم با «INVEST» منطبق است. «INVEST» عبارت است از مخفف: 
  • مستقل (Independent): باید خودبسنده باشد و به سایر داستانها وابسته نباشد.
  • قابل مذاکره (Negotiable): داستانهای کاربری که بخشی از یک اسپرینت هستند همیشه قابل تغییر و بازنویسی هستند.
  • با ارزش (Valuable): یک داستان کاربر باید به کاربر نهایی، ارزشی را ارائه دهد.
  • قابل برآورد (Estimable): همیشه باید بتوان اندازۀ داستان کاربر را تخمین زد.
  • اندازۀ مناسب (Sized appropriately): داستانهای کاربر نباید آن قدر بزرگ باشند که تبدیلشان به یک طرح یا وظیفه یا امر اولویت‌بندی شده با درجۀ مشخصی ممکن نباشد.
  • قابل آزمون (Testable): داستان کاربر یا توصیفات مربوط به آن باید اطلاعات ضروری برای آزمودن آن را فراهم کنند.

تعیین اندازۀ backlog
تعیین اندازۀ product backlog  عبارت است از اندازه‌گیری سرعتی که تیم اسکرام می‌تواند مؤلفه‌های آن را ارائه کند. افراد در تخمین کار خوب عمل نمی‌کنند. همگی می‌دانیم که در تخمین دقیق اینکه چقدر طول می‌کشد تا یک کار را به طور کامل انجام دهیم، تا چه اندازه بد عمل می‌کنیم. تا کنون چند مرتبه این اتفاق افتاده است که از کسی بشنویم یا به خودمان بگوییم که 80 درصد کار را انجام داده‌ام و 20 درصد باقی‌ماندۀ آن در یک ساعت انجام خواهد شد. اما هنوز بعد از دو روز انجام نشده است. افراد به طور طبیعی بد تخمین می‌زنند.
ما ممکن است در تخمین زدن خوب نباشیم؛ اما در مقایسه کردن اشیاء با یکدیگر عالی هستیم. به عنوان مثال قادریم که با نگاه انداختن به دو دستور پخت غذا تشخیص دهیم که کدام‌یک پیچیده‌تر از دیگری است؛ بدون آنکه تخصصی در آشپزی داشته باشیم. به دو چیز نگاه می‌کنیم و تشخیص می‌دهیم که کدام‌یک بزرگتر از دیگری است. تخمین اندازۀ backlog تماماً یعنی تصمیم‌گیری دربارۀ پیچیدگی و مقدار کار لازم، نه اینکه چقدر طول می‌کشد تا این کار انجام شود. تخمین اندازه با تخمین برابر نیست.
ممکن است بپرسید که چگونه می‌توان زمان انجام برخی چیزها را اندازه گرفت؟ مدیری را در نظر بگیرید که می‌خواهد بداند چقدر طول می‌کشد تیم شما یک widget را تولید کند. شما می‌توانید تخمین زمان کامل شدن widget  را از پیچیدگی widget تخمین بزنید. شما می‌توانید وقتی که تیم از یک اسپرینت فارغ شد، به آن اسپرینت نگاه کرده و محاسبه کنید که چقدر طول می‌کشد تا کار کامل شود. فقط پیچیدگی یک وظیفه‌ی مورد توجه تیم است.
اجازه دهید برای توضیح بهتر چگونگی تخمین مقدار کار مورد نیاز برای کامل شدن کار، این مسأله را با رنگ‌آمیزی خانه‌تان مقایسه کنیم. شما به فروشگاه رنگ فروشی رفته و چند سطل رنگ را برای رنگ‌آمیزی خانه می‌خرید. سپس از سه پیمانکار می‌خواهید که انجام این کار را برای شما تخمین بزنند. اولین پیمانکار به خانه‌ی شما آمده و دور خانه قدم زده و به سطلهای رنگی که خریده‌اید نگاه کرده  و می‌گوید که وی با یک نردبان زنگ زده و برس‌های دستی و پسرکی لاغراندام به عنوان دستیارش، این کار را در ظرف دو روز انجام می‌دهد.
دومین پیمانکار دور خانه قدم زده و به سطلها نگریسته و می‌گوید که به تازگی نردبان و برس‌هایی خریداری کرده است و تیم محلی فوتبال در آخر هفته به وی کمک خواهند کرد. با این دستیاران و تجهیزات جدید، انجام این کار فقط یک روز به طول می‌انجامد.
سومین پیمانکار دور خانه قدم زده و به رنگها نگریسته و می‌گوید که وی صاحب یک دستگاه مکانیکی رنگ‌آمیزی است که باعث می‌شود انجام این کار حدود یک ساعت وقت بگیرد.
شما دربارۀ این ماجرا و سه نوع تخمین از رنگ‌آمیزی خانه، چگونه فکر می‌کنید در صورتی که در هیچ کدام از این سه وضعیت، نه ابعاد خانه تغییری کرده است و نه مقدار رنگی که شما خریداری کرده‌اید.  نکتۀ این داستان در این است که بهترین چیزی که شما می‌توانید انجام دهید تخمین مدت زمان انجام کار نیست؛ بلکه به جای آن باید مقدار تلاشی را که منجر به اتمام کار خواهد شد، تخمین زد. با تخمین مقدار کار می‌توان مدت زمان انجام کار را به دست آورد.

Sprint Backlog
sprint backlog لیستی از همۀ کارهای باقی‌مانده در یک اسپرینت است و باید توسط تیم انجام شود. sprint backlog زیرمجموعه‌ای از product backlog است. product backlog همۀ داستانهای کاربران را که برای product مانده لیست می‌کند؛ اما sprint backlog حاوی همه‌ی داستان‌ها و وظایف باقی‌مانده برای اسپرینت است. نوعاً هنگامی که یک داستان کاربر برای یک اسپرینت انتخاب می‌شود، تیم، آن داستان کاربر را به تعدادی وظیفه تقسیم می‌کند.
یک وظیفه، تکۀ کوچکی از داستان کاربر است که توسط هر عضو تیم قابل انجام است. مثلاً وظایفی از قبیل اجرای تغییرات بر روی بانک اطلاعاتی مورد نیاز یک داستان کاربر یا وظیفۀ اجرای UI برای داستان کاربر. وظایفی که بر روی تابلوی وظایف – که با عنوان Kanban (معادل ژاپنی بیلبورد) نیز شناخته می‌شود- برای همۀ تیم قابل رؤیت است. سایر مؤلفه‌های روی این تخته به همان ترتیب، حاوی اطلاعاتی دربارۀ قرار ملاقاتهای جمع‌آوری نیازمندیها، کنترلهای بازبینی، تحقیقات، آزمون، طراحی و مراحل کد نویسی هستند. شکل 4-2 یک مثال را نشان می‌دهد.
اعضای تیم یک کارت از تخته برداشته و در طول اسپرینت اقدام به انجام وظیفه‌ای که روی کارت توصیف شده، می‌نمایند. در خلال مدتی که تیم بر روی وظایف کار می‌کند، سایر وظایف بروز پیدا کرده و تخمینهای اصلی مجدداً تنظیم می‌شوند. همۀ اعضای تیم، در قبال به روز رسانی تابلو بر طبق اطلاعات جدید مقید خواهند بود.

شکل 4-2 نمونه‌ای از تابلوی Kaban با یک sprint backlog


sprint backlog اطلاعات مورد نیاز نمودار burn-down را فراهم می‌کند. در پایان هر اسپرینت، sprint backlog خالی می‌شود. هر آیتم باقی مانده‌ای در backlog به product backlog برگردانده شده و مجدداً در کنار سایر داستانهای کاربری موجود در product backlog بعلاوۀ داستانهای کاربری تازه وارد شده، اولویت‌بندی می‌شود. 

Burn-down chart
نمودار burn-down شیوه‌ای بصری برای دنبال کردن چگونگی پیش‌روی یک اسپرینت است. این نمودار کار باقیماندۀ اسپرینت را در هر روز، به صورت گرافیکی همانند شکل 5-2 نشان می‌دهد. معمولاً این نمودار در یک محیط عمومی نمایش داده می‌شود تا هرکسی بتواند آن را ببیند. این کار به ارتباطات میان اعضای تیم و هرکس دیگری در سازمان کمک می‌کند. این نمودار همچنین می‌تواند به عنوان نشانگر وجود یک مسأله در اسپرینت عمل کند که تیم ممکن است بخاطر آن نتوانند به تعهد خود عمل کنند.


معیار پذیرش

اگرچه product backlog ، sprint backlog و نمودار burn-down بخشهای اصلی اسکرام هستند، معیار پذیرش خروجی جانبی بسیار مهمی از فرآیند اسکرام است. بدون معیار پذیرش خوب، یک پروژه محکوم به شکست است.

معیار پذیرش ضرورتاً شفاف کنندۀ داستان است. چنین معیاری مجموعه‌ای از گامهای مختلف را در اختیار توسعه دهنده می‌گذارد که پیش از آنکه کار تمام شده تلقی شود، باید انجام دهد. معیار پذیرش، توسط صاحب محصول ( product owner ) به کمک مشتری ایجاد می‌شود. این معیار انتظار از داستان کاربر را تنظیم می‌کند. استفاده از این معیار درجای خود نقطۀ شروع خوبی برای نوشتن تستهای خودکار یا حتی توسعۀ آزمون محور توسط توسعه‌دهنده است. بدین طریق، توسعه‌دهنده چیزی را تولید می‌کند که مشتری بدان نیاز داشته و آن را می‌خواهد.

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


نقش‌های اسکرام
اسکرام بین افرادی که نسبت به پروژه متعهد هستند و افرادی که فقط ذینفع  محسوب میشوند، تمایز قابل توجه‌ای قائل است. مشهورترین روش برای توضیح این مفهوم تعریف حکایت "Pig & Chicken" میباشد؛ یک خوک و یک جوجه در حال قدم زدن بودند که، یک دفعه جوجه به خوک گفت که: "چرا یک رستوران افتتاح نکنیم؟" خوک هم نگاهی به جوجه کرد و گفت:"ایده  خوبی است ، اسم آن را چه بنامیم؟"  جوجه کمی در مورد این مسئله فکر کرد و گفت:"چرا اسمش را 'گوشت ران خوک و تخم مرغ ها' نگذاریم؟" 
 خوک جواب داد:"فکر نمیکنم جالب باشد چون من متعهد خواهم بود به کار، ولی تو فقط درگیر کار خواهی بود".
بنابراین Pigs همان افراد متعهد به پروژه هستند که وظیفه ساخت، تست، گسترش و توزیع را ایفا میکنند. Chickens در طرف دیگر همان افرادی هستند که کمتر به پروژه تعهد دارند. این افراد همان stackeholder‌ها و یا ذینفعانی هستند که از پروژه منفعت می‌برند، اما در مقابل تحویل پروژه مسئول و پسخگو نیستند.

Pig Roles
نقش‌های عنوان شده در زیر جز نقش‌های Pig هستند که تیم اسکرام را نیز تشکیل میدهند:
  • Scrum Master
  • Product Owner
  • Delivery Team
  • Scrum Master
اگر تیم را موتور پروژه‌ی اسکرام در نظر بگیریم، اسکرام مستر روغنی است که موتور را در حال اجرا نگه می‌دارد. او مسئول این است که مطمئن شود فرآیند اسکرام تفهیم شده و دنبال میشود. اسکرام مستر تسهیل کننده‌ی جلسات تیم و حذف موانعی است که امکان دارد تیم در دوره‌ای از انجام کار خود با آن مواجه شد. او مطمئن خواهد بود که هیچ مانعی به عنوان بازدارنده از رسیدن به اهداف تیم در مقابل آنها وجود ندارد و تیم را از حواس پرتی‌های خارجی ایزوله نگه می‌دارد تا مطمئن شود اعضای تیم دقیقا کاری را به آنها سپرده شده است انجام میدهند. اسکرام مستر با بخش‌های مختلف تیم، از صاحبان محصول گرفته تا تست کنندگان وذینفعان کسب و کار در تعامل است، تا مطمئن شود که تمام اعضای تیم برای پروژه مفید هستند و تمام دست آورد‌های مشترک در اسپرینت را به اشتراک میگذارند. اسکرام مستر را یک مدیر پروژه معمول فرض نکنید؛ چون نقشی که او ایفا میکند بیشتر از نقش یک مدیر پروژه است. مشخصه کلیدی اسکرام مستر "رهبر خدمتگزار است". او رئیس تیم نیست ولی به تیم کمک میکند تا به چیزی که نیاز دارند در این اسپرینت دست یابند. اسکرام مستر به تیم کمک میکند تا کار را به سمتی که خروجی با ارزشی برای مشتری دارد، متمایل کنند. زمانی که مسئله‌ای در داخل تیم بوجود آید، به اسکرام مستر انتقال داده میشود تا این تضاد را مدیریت کند. مواقعی هم وجود دارند که اسکرام مستر در نقش فرمانروا، ایفای نقش میکند. وقتی که یکی از مسئولیت‌های اسکرام مستر مطمئن شدن از این است که تمام روشهای اسکرام توسط اعضای تیم دنبال میشوند، هرمسئله و حمله‌ای در برابر چارچوب اسکرام باید توسط اسکرام مستر رفع شود. این شانس خوش و اینچنین اتفاقی به ندرت خواهد افتاد.

Product Owner
صاحب پروژه یا محصول، مسئول مشخص کردن مشتری و افزایش مقدار کاری است که تیم انجام میدهد. او با مشتریان برای مشخص کردن اینکه خواسته آنها چیست، جلسه تشکیل داده و این نیاز‌ها را اولویت بندی میکنند و تیم هم بر روی آیتم هایی با بیشترین  ارزش برای مشتری، کار خواهد کرد. صاحب محصول همچنین product backlog را مدیریت کرده و تنها شخصی است که میتواند user story‌ها را برای انتقال به اسپرینت، اولویت بندی کند. مسئولیت‌های صاحب محصول در طول اسپرینت از سری مسئولیت‌های نقش Pig به سری مسئولیت‌های نقش Chicken تغییر میکند. یکی دیگر از نقش‌های حیاتی او این است که به عنوان نماینده‌ی مشتری، برای تیم است. صاحب محصول خیلی شبیه به اسکرام مستر میباشد ولی در این بین یک تفاوت اصلی در طبیعت نقش‌های آنها وجود دارد: اسکرام مستر به دنبال بهترین جذابیتهای مورد علاقه تیم در یک اسپرینت بوده؛ در حالی که صاحب محصول به دنبال بهترین جذابیتهای مطلوب مشتری در یک اسپرینت است. در یک تیم اسکرام، صاحب محصول، نقشی است که نمیتوان آن را دست کم گرفت. اگر صاحب محصول کسی باشد که نتواند به طور دقیق نیاز‌های مشتری را به تصویر بکشد، در نتیجه پروژه شکست خواهد خورد.
صاحب محصول کلید اجرایی یک محصول است که ارزشی را برای مشتری و موفقیتی را برای تیم به ارمغان می‌آورد.

Delivery Team
تیم تحویل، گروهی است از افراد که مسئول ارائه واقعی محصول هستند. این تیم معمولا شامل دو تا ده نفر از افراد و همچنین ترکیبی از برنامه نویسان، تست کننده‌ها، طراحان محصول نهایی و اعضایی از سایر نظام‌های ضروری، میباشد. تیم برای انتقال user story و وظایف مرتبط با آن به مرحله بعد بر روی تخته Kanban، تا مرحله‌ی اتمام، بر روی اسپرینت‌ها کار میکند. مشخصه‌ی کلیدی تیم تحویل این است که آنها به صورت یک واحد خود سازمانده می‌باشند. هیج رهبری در جمع آنها وجود ندارد و همه به صورت گروهی تصمیم میگیرند که در هر اسپرینت به انجام چه چیزی میتوانند متعهد شوند. اعضای تیم بار دیگر تصمیم خواهند گرفت که چه ابزاری برای موفقیت پروژه نیاز دارند. چنین سطحی از استقلال در متدولوژی آبشاری بی‌سابقه است! تیم تحویل برای بهینه سازی انعطاف پذیری و بهره وری در نظر گرفته شده‌اند. 
تیم اسکرام ترکیبی از افرادی است با توانمندیهای گوناگون که هرکدام باید با تمام چشم اندازهای محصول در مراتب مختلف آشنا باشند. هریک از اعضای تیم به تنهایی در همه‌ی مباحث نرم افزار ماهر نیستند، اما هر یک از آنها دانش عمومی در همه مباحث را دارند و در قسمت کلی از مفاهیم محصول هم متخصص هستند. تیم تحویل به همراه اسکرام مستر و صاحب محصول، برای تکمیل user story‌ها و به سرانجام رساندن هر اسپرینت، باهم کار میکنند. اسکرام مستر با آمادگی به دنبال بهترین جذابیتهای مورد علاقه تیم در یک اسپرینت است؛ در حالیکه صاحب محصول با آمادگی به دنبال بهترین جذابیتهای مطلوب مشتری در یک اسپرینت است. با وجود این دو نقش، تیم میتواند محصولی که مشتری میخواهد را بسارد.

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

Sprint Planning
قبل از شروع هر sprint، جلسه طرح ریزی برای مشخص کردن اینکه کدام امکان و ویژگی در این sprint قرار بگیرد، برگزار میشود. ویژگی‌ها و امکانات از لیست pb ای (product backlog) که توسط صاحبان (یا صاحب) محصول اولویت بندی شده است، انتخاب خواهند شد. برای بار اول که این نشست و جلسه برای یک پروژه برگزار شود، pb ساخته می‌شود. شما می‌توانید این قسمت را sprint 0 در نظر بگیرید. user stories (گزارشات کاربر) انتخاب شده توسط صاحب محصول، برای قرار گرفتن در print ، به تیم داده میشود و  آنها از طریق یک ابزار کاری بنام Planning Poker، گزارشات مذکور را برای نشان دادن پیچیدگی یک گزارش وابسته به گزارشات دیگر در گروه گزارشات، تغییر اندازه و تغییر حجم میدهند. بار دیگر user story هایی که به اندازه هستند، توسط تیم به وظیفه‌هایی قابل نسبت دادن به یک فرد تبدیل میشوند و یک زمان تخمینی که نشان دهنده‌ی زمان اتمام  برای هر وظیفه است، برای هر وظیفه در نظر گرفته میشود. بار دیگر که تمام این کار‌ها انجام شد ، اعضای  تیم به لیست کامل کارهایی که برای  sprint در نظر گرفته شده‌اند، نگاه خواهند کرد و اگر بتوانند تا اتمام sprint کار را تمام  کنند، تصمیم خواهند گرفت که آن را انجام دهند. این تصمیم گیری به صورت زیر است:
به وسیله 5 انگشت قرار است نظرات خود را ارائه دهند؛ به طوری که اگر عضوی دست خود را با یک انگشت بالا ببرد، بدین معنی است که او درطرح پیشنهادی خیلی تردید دارد و اگر دستی با 5 انگشت بالا رود، به این معنی است که این عضو، به شدت به طرح پیشنهادی مطمئن است. اگر هیج دستی با تعداد انگشت 1 یا 2 از بین دست‌های بالا رفته دیده نشود، لذا تیم به انجام آن کار در sprint جاری متعهد خواهد شد. ولی اگر دستی با تعداد انگشت 1 یا 2 از بین دست‌های بالا رفته دیده شود، در آن صورت  اعضای تیم در مورد دلیل رای عضوی که رایی با ارزش 1 یا 2 داده است، بحث خواهند کرد و با دیگر اعضای تیم برای تحویل گزارشات و وظایف موجود در اسپرینت، متعهد میشوند.
sprint backlog از گزارشات کاربر و وظایفی که باید در sprint تکمیل شوند، ساخته شده است. تمام اعضای تیم در کنار اسکرام مستر و صاحبان محصول در نشست برنامه ریزی اسپرینت درگیر هستند. بار دیگر جلسه برنامه ریزی متشکل از اعضای تیم و بدون صاحبان محصول برای بحث در مورد طراحی سطح بالای سیستم برگزار خواهد شد.

planning poker
planning poker یک بازی است که اعضای تیم را تشویق میکند تا ارزیابی درستی در مورد پیچیدگی گزارش کاربری (user story) که در ارتباط با سایر گزارشات (stories) است، داشته باشند. ابزارهای مورد نیاز برای این بازی خیلی ساده هستند: شما میتوانید از دست خود استفاده کنید؛ یا حتی میتوانید مجموعه کارت‌های Planning Poker را برای انجام بازی، خریداری کنید. برای انجام این بازی، صاحب محصول، گزارش کاربر (user story) را خوانده و برای تیم توضیح خواهد داد. تیم برای پرسیدن سوال در باره این گزارش کاربر، آزاد است. وقتی که تمام سوالات پاسخ داده شدند، اسکرام مستر از اعضای تیم خواهد خواست که یک عدد را به صورت خصوصی که به بهترین شکل پیچیدگی user story را ارئه میکند، تعیین کنید. توجه داشته باشید برای اینکه این انتخاب به صورت سهوی تحت تاثیر انتخاب سایر اعضا نباشد، باید برای دیگران آشکار نشود. بار دیگر  اسکرام مستر از همه میخواهد تا شماره‌های خود را برای همه آشکار کنند. اگر تمام اعضای تیم، یک شماره یکسان را تعیین کرده باشند، آن شماره به user story مورد نظر نسبت داده شده و همه سراغ user story بعدی میروند.
اگر شماره‌ها باهم یکسان نباشند، عضوی با بیشترین  و کمترین شماره، انتخاب شده و از آنها خواسته میشود دلیل تعیین شماره خود را شرح دهند. بعد از بحث، یک راند دیگر از بازی بین اعضایی که یک شماره را برای user story انتخاب کرده‌اند، انجام میشود. این کار تا زمانیکه تیم در یک شماره اتفاق نظر داشته باشند، ادامه خواهد داشت. به طور متوسط برای رسیدن به یک شماره یکسان، بیشتر از 3 راند طول نخواهد کشید. اگر بعد از 3 راند باز هم به شماره‌ای که همه با آن موافق هستند، دست نیابند، ما به اسکرام مستر پیشنهاد میکنیم که میانگین را انتخاب کرده و سراغ user story بعدی بروند.

Daily Stand Ups 
در طول یک اسپرینت، تیم، اسکرام مستر و صاحب محصول، برای حضور در جلسات روزانه که یکبار در هر روز و در یک مکان و زمان یکسان برای بحث در مورد موضوع‌هایی که موجب مانع از اتمام کار میشوند، متعهد میشوند. در جلساتی که برگزار میشود، همه به صورت ایستاده بوده و زمان آن بیشتر از 15 دقیقه طول نخواهد کشید. هرکسی که به نوعی ذینفع در پروژه هستند، برای حضور در جلسات دعوت میشوند. هر چند فقط افرادی که رده بندی شده‌اند، اجازه صحبت در این جلسات را خواهند داشت. در این جلسات، هر عضو تیم به 3 سوال زیر پاسخ خواهد داد:
  1. شما چه چیزی را از دیروز تا حالا انجام داده‌اید؟
  2. شما چه برنامه‌ای برای امروز دارید؟
  3. آیا شما مشکل دیگری که مانع رسیدن به هدفتان باشد، ندارید؟ چه جریانی باعث ایجاد این موانع شده‌اند؟ آیا میتوان مانع را حذف کرد یا باید تشدید شود؟

Sprint Review
 جلسه "بررسی اسپرینت" در پایان اسپرینت برگزار میشود. هدف از آن ارائه گزارشات کاربری  (user stories) هست که در طول اسپرینت تکمیل شده‌اند. تیم، صاحب محصول  و اسکرام مستر به همراه سایر ذینفعان، مخصوصا مدیران و مشتریان، در این جلسه حضور خواهند داشت. این بررسی شامل یک دموی غیررسمی از نرم افزار توسعه داده شده در اسپرینت، میباشد. این جلسه دموی محصول، فرصتی است برای مشتری تا بازخورد‌های خود از محصول را به تیم توسعه انتقال دهند. هدف اصلی از این بازنگری، نمایش محصول با کارکرد واقعی است. این جلسه با اصل "بالاترین اولویت ما عبارت است از راضی کردن مشتری با تحویل سریع و مداوم نرم افزار با ارزش" چابک در یک راستا میباشد.
مطالب
تهیه یک Clone از مخزن کدی در گوگل کد

برای مثال پروژه "unhaddins" را در نظر بگیرید. این پروژه یک سری افزونه را جهت کار ساده‌تر با NHibernate ارائه داده است. برای مثال چگونه با WPF یا WCF و امثال آن بتوان به سادگی با NHibernate ارتباط برقرار کرد. این پروژه خروجی قابل دریافتی ندارد؛ به عبارتی یک سری سورس کد است. دریافت یک مخزن کد هم که از گوگل کد در این سمت مشکل است ... اما راه بهتری هم وجود دارد. یکی از خواص کار با سورس کنترل‌ها، امکان تهیه یک clone از یک مخزن کد است. تمام پروژه‌های موجود در گوگل کد هم به این شکل با SVN در دسترس هستند:
http://someproject.googlecode.com/svn/trunk/
که به جای someproject ، نام پروژه مورد نظر قرار خواهد گرفت.

برای نمونه، در سایت https://bitbucket.org ثبت نام کنید. سپس گزینه ایجاد یک مخزن جدید را انتخاب کرده:



و در صفحه‌ی باز شده، گزینه‌ی Import from Subversion را انتخاب کنید:



در اینجا Url خواسته شده باید شبیه به همان آدرس trunk فوق باشد و اگر تیک private فعال باشد (که هست)،‌ دیگران امکان دسترسی به مخزن کد شما را نخواهند داشت. البته این تنظیم پس از دریافت، در برگه‌ی Admin مخزن ایجاد شده نیز قابل تغییر است.

به علاوه سایت github.com هم هر چند بر اساس Git کار می‌کند، اما امکان تهیه یک کپی مطابق اصل از یک مخزن کد SVN را هم دارد؛ به شرح زیر:

یک اکانت رایگان در GitHub درست کنید. بعد یک مخزن خالی جدید را ایجاد کرده و در همان صفحه روی لینک Import a Subversion Repository کلیک کنید و آدرس svn مورد نظر را بدهید.

البته GitHub در دریافت پروژه unhaddins موفق عمل نکرد، اما bitbucket خیلی سریع کل آن‌را دریافت نمود.