Datgs' Blog

Quyết chiến quyết thắng !

Archive for the category “.NET”

Tiers và Layers

Dân IT thì chẳng ai là không biết Tier và Layer và cũng thường sử dụng phiên phiến. Nhưng ở đây có những sự khác biệt:

Layers: cách bạn tổ chức mã nguồn thành các tầng logic, và đơn thuần chỉ là như vậy. Đơn giản nhất là trong lập trình .NET thường nói đến 3tiers: Presentation , Business và Data (nhưng về mặt logic chỉ có thể coi là 3 layers)

Tier: Là nói đến mức vật lý, cụ thể hơn, tier trực tiếp nói về nơi mà mã nguồn được thực thi. Tức là nơi mà layer được triển khai.

Ví dụ nói đến DATA TIER là nói đến database, filesystem … nhưng ngay tại DATA TIER đã cài đặt trong đó những logic layer… (sẽ update sau)

Design Pattern – Creational Pattern – Factory Method

1) Một phương án giải quyết vấn đề tạo object.

2) Câu hỏi là: Làm sao để tạo object mà không cần phải chỉ rõ class cụ thể của object đó là gì?

3) Lợi ích: cho phép chỉ rõ “nội dung” của đối tượng cần tạo. Thường sử dụng các hàm static.

4) Ví dụ về hàm tạo theo cách đặt tên mô tả:

class Complex
{
     public static Complex fromCartesian(double real, double imag) {
         return new Complex(real, imag);
     }

     public static Complex fromPolar(double modulus, double angle) {
         return new Complex(modulus * cos(angle), modulus * sin(angle));
     }

     private Complex(double a, double b) {
         //...
     }
}

Complex c = Complex.fromPolar(1, pi); // Same as fromCartesian(-1, 0)

5) Ví dụ về hàm tạo theo các đóng gói:

public interface ImageReader {
    public DecodedImage getDecodedImage();
}

public class GifReader implements ImageReader {
    public DecodedImage getDecodedImage() {
        return decodedImage;
    }
}

public class JpegReader implements ImageReader {
    // ....
}
public class ImageReaderFactory {
    public static ImageReader getImageReader(InputStream is) {
        int imageType = determineImageType(is);

        switch(imageType) {
            case ImageReaderFactory.GIF:
                return new GifReader(is);
            case ImageReaderFactory.JPEG:
                return new JpegReader(is);
            // etc.
        }
    }
}

6) Hạn chế:

- Nếu hàm tạo (construct method) của class là private, sẽ không tạo được object bằng hàm tạo, mà buộc phải sử dụng hàm factory.
- Không thể mở rộng (kế thừa thêm nữa) ở các subclass nếu hàm tạo là private.
- Không còn đúng cho các subclass. Nếu có subclass gọi hàm factory, nó trả về instance của class chứ khôngphải là nó.

- Giải quyết: cần phải có sự hỗ trợ thêm nữa của các ngôn ngữ lập trình.

LINQ, là gì và tại sao

LINQ ra đời bởi vì cách viết Entity trước đây tạo ra quá là nhiều code nhưng lại có thể dùng auto coding (xài Code Smith chẳng hạn). Có thể ở background, MS có thuê mấy thèng viết Code Smith làm LINKQ cũng nên ^^.

Tóm lại LINQ ra đời để giảm công sức cho những quá trình đơn giản và “chung chung” trước đây.

Đó là nỗ lực kết xuất truy vấn ra Entity Object. Lập trình viên sẽ không phải care đến việc viết các Entities nữa.

Điểm mạnh (chưa chắc về độ mạnh, nhưng hay) của LINQ là “viết truy vấn cho rất nhiều các đối tượng dữ liệu”. Từ CSDL, XML Data Object … thậm chí là viết truy vấn cho một biến mảng đã tạo ra trước đó. Vì vậy mới có các khái niệm LinQ to SQL, LinQ to XML, blo bla ….

Thích nhất là cái “truy vấn cho một biến mảng” (mình xin không được comments nhiều về biến mảng, vì mình không phải là dân .NET, trong khi hình như là C#, VB.NET có một vài kiểu định nghĩa List, Generics Collection gì gì đó ). Trường hợp bạn muốn sắp xếp lại mảng đó, bạn có thể sử dụng LINQ thay vì viết vòng lặp FOR/WHILE như trước.

Tuy nhiên so với mô hình Entity (Entity Framework), LINQ có yếu điểm là chậm và thiếu nhất quán (hiện đại tất phải hại điện).

Vì thế, với các ứng dụng cỡ bự, yêu cầu sự ổn định, khả năng scalable cao, tạm thời không nên sử dụng LINQ, hoặc chỉ sử dụng LINQ cho các thành phần cơ bản, ít liên quan đến Business Logic.

Trong các hệ thống lớn, khi bạn cần thay đổi một công thức nào đó chẳng hạn, bạn nên sử dụng một “công thức ngoài mã nguồn”. (Stored Procedure chẳng hạn). Khi đó bạn sẽ không phải sửa code, re-compile lại hệ thống. Khi sử dụng LINQ, chắc chắn bạn sẽ tốn thời gian cho công việc này (viết lại LINQ query, re-compile, re-deploy… rõ ràng là cực kì phiền phức).

Syntax của ngôn ngữ lập trình

Về mặt hình thức thì đúng là các ngôn ngữ giống nhau về syntax. Có thể gọi đó là trào lưu cũng được. Trước đây khi ngôn ngữ C ra đời, nó được trào đón và thực sự vượt hẳn lên trên Pascal trong việc phát triển các hệ thống. Và đẩy Pascal trở về đúng vị trí của nó: một cuốn sách giáo khoa về lập trình. Và các ngôn ngữ sau này, thông thường là Like C.

Những phá cách theo kiểu Python không phải là không được chào đón. Tuy nhiên Like C vẫn được ưa thích hơn cả. Theo chủ quan của anh, và có lẽ cũng là của các lập trình viên khác là có lẽ là vì nó “vừa đủ”. Vừa đủ ngắn và vừa đủ dài (hình thức bao gồm keyword, operator …). C cũng vừa đủ giản đơn cho người mới học lập trình, và cũng đủ phức tạp để thể hiện được ý tưởng của các giải thuật cơ bản. Nó khó học hơn pascal một chút (một chút thôi), nhưng viết mã đơn giản hơn Pascal gấp nhiều lần. Vì vậy lựa chọn C là hợp lý.

Các ngôn ngữ sau này hầu hết được sinh ra từ ngôn ngữ C (tức là xây dựng nên từ các dòng code C).

Về mặt nội dung, mỗi ngôn ngữ lập trình là một công cụ với mục đích cụ thể. Không có ngôn ngữ nào ra đời chỉ để “cho vui”. Sự khác nhau và giống nhau của các ngôn ngữ là ở chỗ “nó được sử dụng để làm gì?”.

Và cũng vì đó là một công cụ, một công cụ dành cho con người sử dụng. Cho nên, không nên nghĩ rằng cái này khó lắm, cái kia khó lắm không học được đâu !!! Mà nên nghĩ rằng cái này chưa biết, cái kia biết rồi. Cũng từa tựa như là việc sử dụng MS Word vậy thôi.

So sánh như vậy là hơi khập khiễng, bởi vì MS Word là công cụ ứng dụng dành cho nhân viên văn phòng (rộng hơn là everybody), còn ngôn ngữ lập trình là công cụ đa năng (và chỉ một số đối tượng được chuyên môn hóa mới có thể tiếp cận được).

Quan trọng nhất của việc sử dụng ngôn ngữ lập trình là tư duy logic, tư duy ở cấp độ con số.

C# Generics

Kiểu mảng cũ

using System;

using System.Collections;

namespace TestApp {

class Test {

[STAThread]

static void Main(string[] args) {

ArrayList list = new ArrayList();

list.Add(3);

list.Add(4);

//list.Add(5.0);

int total = 0;

foreach(int val in list) {

total = total + val;

}

Console.WriteLine( “Total is {0}”, total);

}

}

}

Generics

List<int> aList = new List<int>();

aList.Add(3);

aList.Add(4);

// aList.Add(5.0);

int total = 0;

foreach(int val in aList) {

total = total + val;

}

Console.WriteLine(“Total is {0}”, total);

Viết generics class

//MyList.cs

#region Using directives

using System;

using System.Collections.Generic;

using System.Text;

#endregion

namespace CLRSupportExample {

public class MyList<T> {

private static int objCount = 0;

public MyList() { objCount++; }

public int Count {

get { return objCount; }

}

}

}

//Program.cs

#region Using directives

using System;

using System.Collections.Generic;

using System.Text;

#endregion

namespace CLRSupportExample {

class SampleClass {}

class Program {

static void Main(string[] args) {

MyList<int> myIntList = new MyList<int>();

MyList<int> myIntList2 = new MyList<int>();

MyList<double> myDoubleList = new MyList<double>();

MyList<SampleClass> mySampleList = new MyList<SampleClass>();

Console.WriteLine(myIntList.Count);

Console.WriteLine(myIntList2.Count);

Console.WriteLine(myDoubleList.Count);

Console.WriteLine(mySampleList.Count);

Console.WriteLine( new MyList<sampleclass>().Count);

Console.ReadLine();

}

}

}

Methods với Generics

public class Program {

public static void Copy<T>(List<T> source, List<T> destination){

foreach (T obj in source) {

destination.Add(obj);

}

}

static void Main(string[] args)

{

List<int> lst1 = new List<int>();

lst1.Add(2);

lst1.Add(4);

List<int> lst2 = new List<int>();

Copy(lst1, lst2);

Console.WriteLine(lst2.Count);

}

}

Singleton design pattern

Singleton là một design pattern khá là sơ đẳng. Kiểu lập trình này trong OOP cho phép khởi tạo đối tượng một lần (ví dụ như tạo kết nối với CSDL chẳng hạn, bạn chỉ cần mở kết nối một lần và thực hiện rất nhiều truy vấn trên cùng kết nối đó. Chứ không cần cứ mối truy vấn lại kết nối lại một lần.

Trong C#, Singleton được cài đặt như  sau

class Singleton

{

/* biến static instance, tạo instance một lần ở đây, những lần sau sẽ sử dụng lại*/

private static Singleton instance;

private static int numOfReference;

private string code;


private Singleton()

{

numOfReference = 0;

code = “Maasoom Faraz”;

}


public static Singleton GetInstance()

{

/* rất đơn giản, nếu instance đã tồn tại thì trả về , ngược lại một instance mới sẽ được tạo ra và trả về */


if(instance == null)

{

instance = new Singleton();

}

numOfReference++;

return instance;

}


public static int Reference
{

get { return numOfReference; }

}

public string Code
{

get { return code; }

set { code = value;}

}

}

Observed Pattern Design

public class Parent
{    
     public String Name { getset; }
     public void OnChildCry(Child c){
        Console.WriteLine(this.Name + ” heard “ + c.Name + ” cry”);
    }
}

public class Child
{
    public Child()
    {
        Parents = new List<Parent>();
    }
    public String Name { getset; }
    public List<Parent> Parents { getset; }

     public void Cry()
   {
        foreach(Parent p in Parents)
            p.OnChildCry(this);
    }
}

 class Program
{
    static void Main(string[] args)
    {
        Parent Ralph = new Parent { Name = “Ralph” };
        Child Billy = new Child { Name = “Billy” };
        Parent Mary = new Parent { Name = “Mary” };
         Billy.Parents.Add(Ralph);
        Billy.Parents.Add(Mary);
         Billy.Cry();
         Console.Read();
    }
}

Post Navigation

Follow

Get every new post delivered to your Inbox.