Thảo Trịnh -
  • Agile
  • Chuyện code
    • Design Pattern
    • Blockchain
  • Chuyện đọc
Agile
Chuyện code
    Design Pattern
    Blockchain
Chuyện đọc
  • Agile
  • Chuyện code
    • Design Pattern
    • Blockchain
  • Chuyện đọc
Thảo Trịnh -
Design Pattern

IoC introduction chapter 3

Ở phần trước, chúng ta đã tìm hiểu về cách implement nguyên lý IoC bằng việc sử dụng Factory pattern và đạt được mức độ đầu tiên của việc thiết kế các class có ít sự phụ thuộc hơn.
Phần này chúng ta sẽ tìm hiểu việc implement DIP bằng cách tạo các abstract class.

August 4, 2019by thaotrinh
Design Pattern

IoC Introduction chapter 2

Ở phần này chúng ta sẽ tìm hiểu về IoC và cách để implement nó. Đây là bước đầu tiên để đạt được mục tiêu làm giảm sự phụ thuộc giữa các lớp ứng dụng. Các bước được minh họa theo follow sau:

July 6, 2019by thaotrinh
Design Pattern

IoC Introduction chapter 1

Chắc hẳn các thuật ngữ Inversion of Control (IoC), Dependency Inversion Principle (DIP), Dependency Injection (DI), và IoC containers không còn xa lạ với nhiều người. Tuy nhiên không dễ để làm rõ sự khác nhau giữa các khái niệm này.
Loạt bài viết này cố gắng mang đến cho các bạn cái nhìn tổng quan nhất, với mong muốn cùng các bạn khám phá kiến thức về IoC, DIP, DI..

July 4, 2019by thaotrinh
Design Pattern

Mô hình CQRS-ES

Một trong các đòi hỏi lớn của việc quản lý danh mục sản phẩm là phải thiết kế để đáp ứng các nhu cầu về hiệu năng và tích hợp với các hệ thống khác. Để đáp ứng các yêu cầu tốt, thì phải được thiết kế từ tổng thể ngay từ đầu. Có vậy mới tạo ra sự phát triển liền mạch, nhất quán giúp đảm bảo tính ổn định, cũng như tiến độ làm việc.

June 14, 2019by thaotrinh
Design Pattern

Thiết kế hệ thống phần mềm với mô hình CQRS

Đầu tiên chúng ta bắt đầu với bài toán quản lý sản phẩm với các nghiệp vụ phức tạp. Ví dụ hệ thống quản lý sản phẩm của các trang thương mại điện tử (Amazon, shoppe, tiki..).

Với bất kì sản phẩm phần mềm nào, chúng ta đều có chung mục đích thiết kế:

– DRY (Don’t Repeat Yourself), các nghiệp vụ được phân tách rõ ràng, cô đọng và tập trung cao.
– Có thể mở rộng, sửa đổi các thành phần độc lập.
– Linh hoạt trong việc phát triển.
– Dễ dàng test và bảo trì. Xem thêm

June 12, 2019by thaotrinh
.NET, Design Pattern

Unit Of Work và Repository Pattern – Song kiếm hợp bích

Ở bài trước mình đã giới thiệu với các bạn về UnitOfWork Design Pattern.

Nhắc lại vể lợi ích của UOW

  • Quản lý danh sách các đối tượng logic nghiệp vụ được thay đổi trong một transaction.
  • Khi một transaction được complete, tất cả thay đổi sẽ được gửi tới database như một big unit of work

Bài toán:

Để hình dung rõ hơn, lần này chúng ta sẽ xem xét bài toán thực tế khi quản trị hệ thống muốn xóa một đơn hàng. Chúng ta cần xóa dữ liệu ở 2 bảng Orders và OrderDetails.

Theo cách làm thông thường, chúng ta sẽ xóa dữ liệu bảng OrderDetails trước, sau đó xóa dữ liệu bảng Orders. Với cách làm này rủi ro xảy ra nếu sau khi xóa dữ liệu bảng OrderDetails xong, một exception xảy ra (ví dụ kinh điển là mất mạng) lúc này dữ liệu bảng Orders chưa được xóa, dẫn tới việc không đảm bảo tính toàn vẹn dữ liệu và có thể gây lỗi hệ thống khi truy xuất đơn hàng.

Để giải quyết bài toán này. Chúng ta sử dụng pattern UnitOfWork, thực hiện việc xóa dữ liệu ở 2 bảng trong cùng 1 transaction. Bất kì ngoại lệ nào xảy ra, dữ liệu sẽ được rollback. Nếu thao tác xóa dữ liệu thành công, transaction sẽ được commit.

Đồ nghề:

  • Database mẫu.

Xây dựng hệ thống

Cùng xem xét lại quan điểm:
Simplicity is the ultimate sophistication
Áp dụng thực tế vào bài toán khi làm việc với Database, để tránh việc code thừa ở khắp nơi khi gọi query dữ liệu. Trong ví dụ này chúng ta dùng thêm repository pattern để xử lý tầng kiến trúc làm việc với database.

Với tư tưởng như trên, chúng ta xây dựng lớp Repository chuyên xử lý các thao tác thông thường với database. Lớp OrderRepository xử lý các vấn đề đặc thù của Domain Order

Cấu trúc dự án tổng thể như sau:

Đầu tiên chúng ta xây dựng interface IRepository

public interface IRepository<TEntity> where TEntity : class { TEntity Get(int id); IEnumerable<TEntity> GetAll(); IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate); TEntity SingleOrDefault(Expression<Func<TEntity, bool>> predicate); void Add(TEntity entity); void AddRange(IEnumerable<TEntity> entities); void Remove(TEntity entity); void RemoveRange(IEnumerable<TEntity> entities); } Xem thêm

June 8, 2019by thaotrinh
Design Pattern

Unit of Work Design Pattern

Trong bài viết này, chúng ta sẽ cùng thảo luận về Unit of Work Design Pattern.

Nội dung chính:

  • Lợi ích khi sử dụng Unit of Work design pattern?
  • Work và Unit trong ứng dụng phần mềm.
  • Logical transaction! = Physical CRUD.
  • So sánh với một transaction.
  • Ý tưởng việc implement UOW.
  • Code demo C#

Lợi ích khi sử dụng Unit of Work design pattern?

Khái niệm UOW

  • First it maintains in-memory updates.
  • Second it sends these in-memory updates as one transaction to the database.

Giải thích

– Thứ 1: uow quản lý các trạng thái cập nhật dữ liệu trong bộ nhớ.

– Thứ 2: uow thực hiện cập nhật tất cả dữ liệu trong bộ nhớ “như là – một transaction” vào database.

Từ khái niệm trên, chúng ta rút ra được lợi ích khi sử dụng uow

  • Quản lý danh sách các đối tượng logic nghiệp vụ được thay đổi trong một transaction.
  • Khi một transaction được complete, tất cả thay đổi sẽ được gửi tới database như một big unit of work

Work và Unit trong ứng dụng phần mềm.

Một cách đơn giản để định nghĩa Work là: "Thực hiện một vài tác vụ". Các tác vụ ở đây có thể là Thêm, Sửa, Xóa dữ liệu.
Chúng ta có thể cùng xem một ví dụ về việc ứng dụng quản lý khách hàng. Khi chúng ta thêm/sửa/xóa khách hàng trong database, đó là một unit. Kịch bản đơn giản của chúng ta đó là:

1 customer CRUD = 1 unit of work

Logical transaction! = Physical CRUD

Trong bài toán thực tế, một khách hàng có thể có nhiều địa chỉ giao hàng khác nhau (địa chỉ nhà, địa chỉ cơ quan…).

Tiếp theo ví dụ trên, chúng ta xem xét ông khách hàng Shiv. Giả sử ông này có 2 địa chỉ, vậy khi thay đổi thông tin của khách hàng Shiv này, chúng ta cần thay đổi 3 bản ghi. Xem xét kịch bản như sau:

3 Customer CRUD = 1 Logical unit of work

Trong các dự án thực tế, chúng ta có thể đưa nhiều tác vụ khác nhau vào một unit of work.

Một ví dụ đơn giản khác, đó chính là bài toán rút tiền tại cây ATM. Khi khách hàng thực hiện rút tiền, ngân hàng cập nhật thông tin bảng giao dịch, cập nhật số dư khách hàng, gửi tin nhắn, in hóa đơn.. Tất cả các tác vụ đó có thể đưa vào một UOW

So sánh với simple transaction

Một UOW sẽ rất khác với một transaciton database. UOW chỉ gửi những bản ghi được thay đổi tới database mà không phải tất cả các bản ghi!

Điều này có nghĩa là gì?

Ví dụ ứng dụng của bạn lấy từ DB ra 3 bản ghi dữ liệu, nhưng chỉ thay đổi 2 trong 3 bản ghi đó. UOW chỉ gửi 2 bản ghi được thay đổi này tới DB để tiến hành cập nhật. Việc này giúp tối ưu performance cho hệ thống của bạn.

Tóm lại

1 Unit of work = Modified records in a transaction

Sample code for unit of work

Bước 1: Tạo Interface

Theo phần trước đã thảo luận, chúng ta biết rằng UOW theo dõi và quản lý những thay đổi trong các đối tượng nghiệp vụ.

Bây giờ hãy xem xét bài toán với rất nhiều các đối tượng nghiệp vụ với nhiều kiểu khác nhau. Ví dụ bạn có thể có customer, suplier, account…Các đối tượng này chính là các entities mà UOW quan tâm và xử lý.

Xem xét kiến trúc sau

Với thiết kế UOW tracking nhiều đối tượng, chúng ta có thể giảm thiểu rất nhiều số mã trùng lặp.

Đầu tiên chúng ta tạo interface IEntity  như sau:

public interface IEntity
{
    int Id { set; get; }
    void Insert();
    void Update();
    List<IEntity> Load();
}

Các đối tượng Customer, Supplier, Order sẽ implement interface này, theo kiến trúc đơn giản như sau:

Bước 2: Implement the IEntity interface

public class Customer : IEntity { private int _CustomerCode = 0; public int Id { get { return _CustomerCode; } set { _CustomerCode = value; } } private string _CustomerName = ""; public string CustomerName { get { return _CustomerName; } set { _CustomerName = value; } } public void Insert() { DataAccess obj = new DataAccess(); obj.InsertCustomer(_CustomerCode, CustomerName); } public List<IEntity> Load() { DataAccess obj = new DataAccess(); Customer o = new Customer(); SqlDataReader ds = obj.GetCustomer(Id); while (ds.Read()) { o.CustomerName = ds["CustomerName"].ToString(); } List<IEntity> Li = (new List<Customer>()).ToList<IEntity>(); Li.Add((IEntity) o); return Li; } public void Update() { DataAccess obj = new DataAccess(); obj.UpdateCustomer(_CustomerCode, CustomerName); } } Xem thêm

May 20, 2019by thaotrinh
Design Pattern

Nguyên lý SOLID trong lập trình hướng đối tượng – và ví dụ sử dụng C# – p4

Tìm hểu về “I” – ISP (Interface Segregation principle)

Thay vì dùng 1 interface lớn, ta nên tách thành nhiều interface nhỏ, với nhiều mục đích cụ thể

Nguyên lý này khá dễ hiểu. Hãy tưởng tượng chúng ta có 1 interface lớn, khoảng 100 methods. Việc implements sẽ khá cực khổ, ngoài ra còn có thể dư thừa vì 1 class không cần dùng hết 100 method. Khi tách interface ra thành nhiều interface nhỏ, gồm các method liên quan tới nhau, việc implement và quản lý sẽ dễ hơn. Xem thêm

June 24, 2016by thaotrinh
Design Pattern

Nguyên lý SOLID trong lập trình hướng đối tượng – và ví dụ sử dụng C# – p3

Tìm hiểu về “L”- LSP (Liskov substitution principle)

Nguyên lý được phát biểu như sau:

So LISKOV principle says the parent should easily replace the child object.
Trong một chương trình, các object của class con có thể thay thế class cha mà không làm thay đổi tính đúng đắn của chương trình

June 23, 2016by thaotrinh
Design Pattern

Nguyên lý SOLID trong lập trình hướng đối tượng – và ví dụ sử dụng C# – p2

  • SOLID “S” – SRP (Single responsibility principle)
  • SOLID “O” – Open closed principle
  • SOLID “L” – LSP (Liskov substitution principle)
  • SOLID “I” – ISP (Interface Segregation principle)
  • SOLID “D” – Dependency inversion principle

Hiểu về “O” – Open closed principle

Bây giờ chúng ta sẽ tiếp tục với class Customer ở ví dụ trước. Tôi sẽ thêm một property đơn giản vào lớp này. Property này sẽ chỉ ra kiểu “customer” sẽ là “Gold” hay “Silver”.

Sau đó với một vài tính toán đơn giản với hàm “GetDiscount” chúng ta sẽ tính toán discount cho khách hàng.

Cùng xem đoạn code sau:

class Customer
{
  private int _CustType;

  public int CustType
  {
    get { return _CustType; }
    set { _CustType = value; }
  }

  public double getDiscount(double TotalSales)
  {
    if (_CustType == 1)
      return TotalSales - 100;
    else
      return TotalSales - 50;
  }
}

Xem nào, vấn đề ở đây là khi chúng ta muốn thêm một kiểu customer mới, chúng ta sẽ phải thêm 1 câu lệnh điều kiện if vào hàm “getDiscount”. Nói cách khác chúng ta cần thay đổi lớp customer.

Nếu chúng ta thay đổi lớp customer hết lần này đến lần khác, chúng ta cần chắc chắn rằng đoạn code của chúng ta phải được kiểm tra lại (tested again) để đảm bảo rằng chương trình sẽ vẫn hoạt động bình thường. Điều này thật rắc rối và mất công!!!

Vậy bất cứ khi nào bạn gặp vấn đề về “MODIFYING” thì hãy ngay lập tức nghĩ tới “EXTENSION”. Ở trường hợp cụ thể này, chúng ta có thể thêm 1 class mới như đoạn code dưới, để mỗi lần thay đổi, chúng ta chỉ việc kiểm tra lại class mới được thêm vào

class Customer { public virtual double getDiscount(double TotalSales) { return TotalSales; } } class SilverCustomer : Customer { public override double getDiscount(double TotalSales) { return base.getDiscount(TotalSales) - 50; } } Xem thêm

January 31, 2016by thaotrinh
Page 1 of 212»

Tìm kiếm

Bài viết mới

Giá trị của Scrum Master trong case study của Leflair

Giá trị của Scrum Master trong case study của Leflair

Vì sao bạn nên phân tích đối thủ để đưa ra giải pháp thiết kế tốt hơn

Vì sao bạn nên phân tích đối thủ để đưa ra giải pháp thiết kế tốt hơn

Scrum Master làm gì trong suốt một ngày?

Scrum Master làm gì trong suốt một ngày?

Tôi có thể làm gì trong những năm 20 tuổi để giúp phát triển bản thân và cả sự nghiệp của tôi?

Tôi có thể làm gì trong những năm 20 tuổi để giúp phát triển bản thân và cả sự nghiệp của tôi?

Sách đã đọc

Sách đã đọc

Chuyên mục

  • Agile learn
  • Chuyện đọc
  • Gã
  • Lập trình
    • .NET
    • Blockchain
    • Database
    • Design Pattern
    • Lập trình cơ bản
    • Laravel
  • Leading
  • Product
    • Design
  • Uncategorized

Mọi người quan tâm

Nguyên lý SOLID trong lập trình hướng đối tượng – và ví dụ sử dụng C#  – p2

Nguyên lý SOLID trong lập trình hướng đối tượng – và ví dụ sử dụng C# – p2

Tạo ứng dụng blockchain đầu tiên với C#

Tạo ứng dụng blockchain đầu tiên với C#

Cài đặt và cấu hình Apache, MySQL trên macos

Nguyên lý SOLID trong lập trình hướng đối tượng – và ví dụ sử dụng C#  – p3

Nguyên lý SOLID trong lập trình hướng đối tượng – và ví dụ sử dụng C# – p3

Nguyên lý SOLID trong lập trình hướng đối tượng – và ví dụ sử dụng C# – p1

Nguyên lý SOLID trong lập trình hướng đối tượng – và ví dụ sử dụng C# – p1

Tags

Agile Apache blockchain C# Case study CQRS Daily Scrum database DDD deadlocks Dependency Injection Dependency Inversion Design Pattern docker ebook fix mindset git Good Developer growth mindset kinh tế Pair programing Repository Retrospectives Risk Management Scrum Scrumban Scrum Guide Scrum Master Senior Senior Developer singleton solid Technical debt UI UnitOfWork UX Viết Động lực

Lịch sử

  • February 2021
  • January 2021
  • December 2020
  • November 2020
  • September 2020
  • August 2020
  • June 2020
  • April 2020
  • March 2020
  • December 2019
  • November 2019
  • September 2019
  • August 2019
  • July 2019
  • June 2019
  • May 2019
  • April 2019
  • March 2019
  • November 2018
  • September 2018
  • July 2018
  • June 2018
  • March 2018
  • January 2018
  • December 2017
  • June 2017
  • May 2017
  • October 2016
  • August 2016
  • June 2016
  • March 2016
  • January 2016
  • December 2015
  • March 2015