JS là 1 ngôn ngữ lập trình thú vị nhất mình từng biết. Cùng với python, mình nghĩ đây 2 NNLT hay nhất mà ai cũng nên học.

Xem ví dụ sau, cho x bằng:


> x=[0]
< [0]

Thử so sánh như thế này xem


x == x
< true

Hợp lý đấy chứ, nhưng thử phủ định xem sao :


> x == !x
< true

Vì sao, là vì toán tử ! trên js nó rất khác thường, không như đa phần các NNLT khác, toán tử ! chỉ dùng cho toán hạng là số nguyên, thì toán tử ! của x dùng cho rất nhiều thể loại, và nếu sau đó là 1 mảng thì nó sẽ trả về là true. Và, ở toán tử == thì mọi thứ sẽ ép kiểu sao cho toán hạng trái sẽ cùng kiểu toán hạng phải, lúc này x ép kiểu về boolean thì tự nhiên nó cũng là true Khá thú vị phải ko =]] Tiếp tục, so sánh


> typeof NaN
< "number"

Haha, NaN là 1 thành phần của lớp Number đấy các bạn. Và NaN chính là Number.NaN


> typeof null
< "object"

Null là 1 Object cực kỳ đặc biệt, nếu nhìn qua các thể loại NNLT khác, có thể thấy null nó là 1 thực thể khó hiểu trong vũ trụ :)) Ví dụ trên sql, muốn so sánh với null phải dùng “is” chứ không cho dùng “=”


> null instanceof Object
null == null
< false

Như vậy có thể thấy null không thể là instance của bất cứ cái gì, kể cả là chính nó =]]


> 9999999999999999
< 10000000000000000

Overload number nên làm tròn luôn :v


> 0.1 + 0.2 == 0.3
< false

Không phải chỉ mỗi javascript bị lỗi này, rất nhiều NNLT cũng bị bệnh này, là do số float khi convert qua binary để thực hiện các phép cộng trên máy, lúc convert về kết quả, nếu trình biên dịch không chịu làm tròn thì nó sẽ ra kiểu như vầy 0.1 + 0.2 = 0.30000000000000001 Như vậy nó khác 0.3 là chuẩn rồi


> Math.max()>Math.min()
< false

Toán tử > vô dụng trong TH này

> Math.max()<Math.min()
< true

Toán tử < cũng vô dụng trong TH này =]]


> []+[]
< ""

[]+{}
< "[object Object]"

{}+[]
< 0

{}+{}
< NaN

Đây chính xác là vẻ đẹp của javascript: Toán tử cộng.


> true+true===2
true-true===0
< true

Việc ép kiểu cho các phép toán boolean như === cũng rất bất ngờ :))


> "2" * "2" === 4
"2" + "2" === 4
< false

Có thể thấy toán tử cộng sẽ ưu tiên cộng chuỗi trước phép toán. Nên “2” + “2” sẽ là “22” trước.
Còn phép nhân, nó sẽ ép kiểu 2 toán hạng cho ra kiểu dữ liệu cuối cùng bị gán về.
Ở ví dụ trên, khi x === 4 thì x sẽ bị ép kiểu về integer vì toán tử === ép 2 bên về cùng 1 kiểu dữ liệu bên phải.
và “2” * “2” phải là kiểu integer, nên phép nhân ép 2 toán hạng 2 bên về integer nốt. Và thực hiện phép nhân 2 * 2 === 4 là chuẩn rồi

Tham khảo:

https://charlieharvey.org.uk/page/javascript_the_weird_parts

Phía sau 1 Node.JS

Posted: January 23, 2017 in backend

Nodejs được thần thánh hóa khắp nơi, mình cũng có thời gian dùng nó vào projects của mình, và có 1 số kiến thức nhất định về mô hình này.

– Đây chắc là 1 trong những dự án mà ý tưởng hình thành có lẽ được mấy người đó viết ra để chống C10k

– Nodejs dùng V8 Engine để dịch code và thực thi code javascript, nên có tốc độ nhanh, ổn định, nên có thể tận dùng nguồn lực dev js frontend để invoke vào làm node.js.

– Hoạt động trên 1 single-thread trên 1 process : nên tốc độ cao ( vì không gọi các hàm fork, create thread và dùng memory space để lưu trữ thread, cũng như bỏ các giai đoạn context switch ..) , cũng như còn tránh các vấn đề về threadsafe, race condition, mutex…

– Non-blocking với socket : Yêu cầu thực thi operation và trả về ngay lập tức. Nếu chưa sẵn sàng để thực hiện thì thử lại sau. Tương đương với kiểm tra operation có ready ngay hay không, nếu có thì thực hiện và trả về, nếu không thì thông báo thử lại sau.

– Mô hình Nonblocking I/O trên nodejs:

  •         Với các dạng Slow IO : dùng IO multiplexing : poll, select , epoll, kết quả trả về ngay khi ready.
  •         Với dạng Fast IO :  dùng ThreadPool : là mô hình multithread kết hợp 1 threadpool để quản lý, kết quả trả về liền.

Các dạng IO thông dụng :

  •         Block Device     => Fast
  •         Pipe    => Slow
  •         Socket    => Slow
  •         Regular    => Slow
  •         Directory    => Fast
  •         Character Device    Varies

+ Hàm epoll – xương sống của NodeJS :Giám sát, quản lý các IO và trả về trạng thái (ready or not) để event-loop có thể gọi và sử dụng file đó. Nên nhớ trên Linux, mọi thứ được xem như là 1 file IO.

– Event-loop là 1 thứ dùng để quản lý các callback ( trả về kết quả từ quá trình gọi thực thi vào nonblocking IO) vào 1 callstack, event-loop sẽ lặp đi lặp lại và trả về response tương ứng bất cứ lúc nào các hàm callback có trong callstack có dữ liệu.

– NodeJS được folk từ repo của libuv : Là thư viện xử lý các vấn đề nêu trên (nonblocking-IO) kết hợp cùng V8 tạo nên mô hình là 1 event-loop ( gọi chung là mô hình event-driven ) + Nonblocking I/O và xử lý các request của client, trả về response asynchronize như bọn nó từng quảng cáo.

Tổng kết :

Node.JS có ý tưởng hình thành là khá thú vị, có nhiều service khác cũng sử dụng mô hình nonblocking tương tự như HAProxy, Redis, Nginx ..

Tuy nhiên, nó có 1 số nhược điểm mà mình từng gặp, là việc dùng 1 thread, sẽ gặp 1 số vấn đề khi không khai thác hết những hệ thống có tài nguyên dồi dào như CPU có nhiều core chẳn hạn .. Lúc này, ta cần dùng 1 đầu proxy để phân tải ra nhiều instance nodejs khác nhau, thì vấn đề đồng bộ session, id .., và các bài toán về đồng bộ, phân hoạch request .. cần phải xử lý.

Ngoài ra, khi làm việc với các mô hình blocking, hay các lib blocking xử lý ảnh, xử lý bản vẽ kỹ thuật .. thì nodejs cũng không khá hơn dùng các mô hình khác, mà còn có khi tệ hơn vì đã chiếm dụng hết cpu usage để event loop hoạt động.

Tuy nhiên, với 1 dự án start-up, thiếu điều kiện, mà phải serve 1 lượng lớn request, thì nodejs là giải pháp khá ổn.

Mô hình tốt cho 1 dự án start-up : Nodejs + Nginx(hoặc HAProxy) + Redis + Mysql( hoặc MongoDB tùy hoàn cảnh). Đây là mô hình mình đã dùng để build project cho các nhà đầu tư ít vốn ( cùng wordpress, lavarel ).

Tham khảo nhiều từ :

http://en.sotatek.com/nodejs-hieu-asynchronous-event-drivent-nonblocking-io/

1 số thứ cẩn nhớ :

Cẩn chú ý, nếu vi phạm checklist sau, xác nhận bị reject

App crash 
App có bug thấy rõ
App không giống như mình nói
App có những thứ ẩn mà ko thể hiện trong phần description
App dùng API non-public
App đọc ghi dữ liệu ngoài vùng app chỉ định
App download code từ nơi khác
App chạy 1 đoạn code khác ngoài chương trình
App phải release, không có các version “demo”, “trial”, or “test”
App viết cho iphone phải chạy dc trên ipad mà không cần thêm app khác
App vô dụng hoặc chỉ lấy website về hoặc quá chán
App chỉ để quảng cáo kiếm tiền
App ẩn 1 số chức năng cũng như mánh lới trong đó
App >100MB phải được update về
Multitasking App dùng cho VoIP, audio playback, location, task completion, local notifications
Webview của App phải dùng iOS WebKit framework and WebKit Javascript
App khuyến khích bia rượu thuốc lá cho trẻ em
App cung cấp sai về các chuẩn đoán ( bệnh tật, hư hỏng …)
App spam ( dùng nhiều version khác nhau cho 1 app)
App phải submit nhạc sách trên store mới lấy dùng
App bắt buộc người dùng chấp nhận policy nếu ko ko cho xài
App phải theo guiline của ios storage data
App dùng ứng dụng khác đặt zô của mình, gây nhầm lẫn
App giới thiệu app khác phải nói rõ hoàn cảnh, mục đích

Content :
Đề cập đến tên của bất kỳ nền tảng di động khác
Dùng placeholder text
Image video … khác với content
AppStore name ko giống với appDevice name
Icon các size ko giống nhau về nội dung
Apps với các biểu tượng ứng dụng, ảnh chụp màn hình, xem trước, và hình ảnh hiển thị khi một ứng dụng Apple TV là ở kệ trên cùng của màn hình TV nhà Apple mà không tuân thủ các 4+ rating
Ứng dụng với loại và lựa chọn thể loại ko thích hợp cho các nội dung ứng dụng
Rating ko đúng vs content
Từ khóa trên store ko liên quan
Gian lận để rating ( các chiêu trò dụ đánh giá …)
Bắt users khởi động lại máy
NÊN có phẩn urls để users tìm hiểu, feedback
Quảng cáo không ghi rõ vật phẩm cần mua, mập mờ
App Preview chụp ko nguyên thủy, thêm texture .. vào
Hiển thị thông tin cá nhân ko xin phép
Music ko phù hợp vs lãnh thổ
App show 1 đoạn nội dung ko bản quyền do lấy từ đâu đó (image, video ..)

Location :
lấy location mà ko báo
Dùng location điều khiển xe máy bay…
Dùng location để làm dịch vụ cảnh báo nguy hiểm
Location chỉ dùng cho nội dung app đưa ra nói rõ

Push Notifications :
Không dùng Apple Push Notification
Không dùng Push Application ID
Không dược user cho
Đưa thông tin nhạy cảm lên notifications
Đưa thông tin lừa Đảo, quảng cáo, trả tiền lên notifications
Dùng để chiếm quá nhiều băng thông
Đưa mã độc, phá hoại

Game Center :
App hiện ra GameID , PlayerID

ADV :
Giả click
Ad bị rỗng
App chèn quảng cáo quá nhiều, chuyên lừa để click

Intellectual Property Rights :
Vi phạm các bản quyền sau : Apple Trademark List , nếu dùng phải theo Guidelines for Using Apple Trademarks and Copyrights
Không Cung cấp thông tin sử dụng từ bên thứ 3 nếu bên đó có thỏa thuận
Tải nhạc ko có bản quyền từ các nguồn youtube…

Media content :
– Không chơi nhạc bằng Music Library
– Bắt chước iPod or iTunes
– stream âm thanh quá lâu : > 5MB 5 phút
+ Lâu hơn 10 phút phải dùng HTTP Live Streaming

User interface :
App giống app nào đó trên App Store, iTunes Store, and iBooks Store
App tạo ra desktop/home screen environments hoặc simulate multi-App
App làm sai chức năng sound on/off …
Giao diện phức tạp khó hiểu, dở

Personal attacks :
Phỉ báng , xúc phạm, gây ảnh hưởng tinh thần đến ai
Châm chọc nhạo báng ẩn ý ai
Có thể thêm cờ để người dùng cảnh báo nội dung khó chịu

Violence :
Ứng dụng mô tả hình ảnh thực tế của người hoặc động vật bị giết hoặc bị thương, bị bắn, bị đâm, bị tra tấn hoặc bị thương
Miêu tả bạo lực hoặc lạm dụng trẻ em
“Kẻ thù” trong bối cảnh của một trò chơi chỉ nhắm mục tiêu một cuộc đối tượng cụ thể, văn hóa, một chính phủ thực hoặc công ty, ..
Miêu tả thực về vũ khí, cách dùng
Các trò chơi ma quỷ, chết chóc

Objectionable content :
Ứng dụng trình bày nội dung quá phản đối hoặc nói lời thô lỗ ai đó
Làm người dùng bối rối, khó chịu hoặc ghê tởm

Privacy :
Tải data về mà ko xin phép
Bắt users chia sẻ personal information, such as email address and date of birth
+ Ứng dụng có thể yêu cầu cho ngày sinh (hoặc sử dụng cơ chế hạn chế tuổi khác) chỉ dành cho các mục đích tuân thủ với luật bảo mật trẻ em áp dụng, nhưng phải bao gồm một số chức năng hữu ích hay giá trị giải trí bất kể tuổi tác của người dùng
Chia sẻ thông tin nhạy cảm về ng dùng, nhất là trẻ em

Khiêu dâm bị cấm dưới mọi hình thức, kể cả ẩn ý

Religion, culture, and ethnicity :
Phỉ báng văn hóa, tôn giáo, dân tộc
Văn bản tôn giáo ko trích đúng

Legal requirements :
Vi phạm luật pháp quốc gia
Khuyến khích tội phạm
Có thông tin, tài liệu phạm pháp

 

C++11 and C+14 WTF

Posted: January 5, 2016 in C/C++

Visual C++ implements the vast majority of features in the C++11 core language specification, as well as many C++14 Library features and some features proposed for C++17. The following table lists C++11/14/17 core language features and their implementation status in Visual C++ in Visual Studio 2010, Visual C++ in Visual Studio 2012, and Visual C++ in Visual Studio 2013, and Visual Studio 2015.

C++11 Core Language Features Visual Studio 2010 Visual Studio 2012 Visual Studio 2013 Visual Studio 2015
Rvalue references v0.1, v1.0, v2.0, v2.1, v3.0 v2.0 v2.1* v2.1* v3.0
ref-qualifiers No No No Yes
Non-static data member initializers No No Yes Yes
Variadic templates v0.9, v1.0 No No Yes Yes
Initializer lists No No Yes Yes
static_assert Yes Yes Yes Yes
auto v0.9, v1.0 v1.0 v1.0 v1.0 Yes
Trailing return types Yes Yes Yes Yes
Lambdas v0.9, v1.0, v1.1 v1.0 v1.1 v1.1 Yes
decltype v1.0, v1.1 v1.0 v1.1** v1.1 Yes
Right angle brackets Yes Yes Yes Yes
Default template arguments for function templates No No Yes Yes
Expression SFINAE No No No No
Alias templates No No Yes Yes
Extern templates Yes Yes Yes Yes
nullptr Yes Yes Yes Yes
Strongly typed enums Partial Yes Yes Yes
Forward declared enums No Yes Yes Yes
Attributes No No No Yes
constexpr No No No Yes
Alignment TR1 Partial Partial Yes
Delegating constructors No No Yes Yes
Inheriting constructors No No No Yes
Explicit conversion operators No No Yes Yes
char16_t/char32_t No No No Yes
Unicode string literals No No No Yes
Raw string literals No No Yes Yes
Universal character names in literals No No No Yes
User-defined literals No No No Yes
Standard-layout and trivial types No Yes Yes Yes
Defaulted and deleted functions No No Yes* Yes
Extended friend declarations Yes Yes Yes Yes
Extended sizeof No No No Yes
Inline namespaces No No No Yes
Unrestricted unions No No No Yes
Local and unnamed types as template arguments Yes Yes Yes Yes
Range-based for-loop No Yes Yes Yes
override and final v0.8, v0.9, v1.0 Partial Yes Yes Yes
Minimal GC support Yes Yes Yes Yes
noexcept No No No Yes

[In This Article]

C++11 Core Language Features: Concurrency Visual Studio 2010 Visual Studio 2012 Visual Studio 2013 Visual Studio 2015
Reworded sequence points N/A N/A N/A Yes
Atomics No Yes Yes Yes
Strong compare and exchange No Yes Yes Yes
Bidirectional fences No Yes Yes Yes
Memory model N/A N/A N/A Yes
Data-dependency ordering No Yes Yes Yes
Data-dependency ordering: function annotation No No No Yes
exception_ptr Yes Yes Yes Yes
quick_exit No No No Yes
Atomics in signal handlers No Yes Yes Yes
Thread-local storage Partial Partial Partial Yes
Magic statics No No No Yes

Optimize source code C++

Posted: December 22, 2015 in C/C++

Today, I really keen on writing a post about my experience during 3 years working with C++. These knowledge will help you improve code skills and performance of your project. Let ‘s go.

Because C++ reach to C++11 and C++14 at the moment, so , this post will update the newest skills. This guide looks like Effective C++.Some knowledge is for senior C++ developer, but , almost is easy to understand for all people.

1/ Switch case is better !!

Suppose you have codes below :

const int value = 15;
switch (value)
{
           case 10:
                   std::cout << value + 1;
                   break;
           case 11:
                   std::cout << value + 2;
                   break;
           case 15:
                   std::cout << value;
                   break;
           default:
                   break;
 }```

The assembly generated by compiler by using switch-case look like :

mov eax,dword ptr [value] 
     mov dword ptr [ebp-0D0h],eax 
     cmp dword ptr [ebp-0D0h],0Ah 
     je wmain+4Bh (case10-adrr) 
     cmp dword ptr [ebp-0D0h],0Bh 
     je wmain+69h (case11-adrr) 
     cmp dword ptr [ebp-0D0h],0Fh 
     je wmain+87h (case15-adrr) 
     jmp wmain+0A0h (default-adrr) ```

You could realize that program will sequentially compare to value of “case” and if something wrong, it will go next step, without jump to anywhere because of opcode “je”.

And with if-else :

int value = 15;
  mov         dword ptr [value],0Fh  
    if(value == 10)
  cmp         dword ptr [value],0Ah  
  jne         wmain+49h (value == 11_adrr)  
    {
        std::cout << value + 1;
    }
    else if(value == 11)
  cmp         dword ptr [value],0Bh  
  jne         wmain+6Dh (value == 15_adrr)  
    {
        std::cout << value + 1;
    }
    else
  jmp         wmain+89h (outofifelse_adrr)  
    {
        std::cout << value + 1;
    }```

Clearly, if-else have to jump more places than switch-case. And, totally , switch-case win 1-0.


2/ add value better than statement = inline function adder

// using inline if possible

// set calculation inside loop outside

// using template if possible

// all params is const ref

// optimize condition

// do not put object to constructor

// should not init so much , not run method(especially virtual method) in constructor

// override carefully ( default param sometime conflict, pay attention to Base method and current method)

// Assign by put data to Class in declare -> class A : Age(age) , Name(name)

// if need => overload operator =;

// put data to function and set value to them, don’t create new object and return inside method

// avoid temporary object

// function with const => int getNumber() const;

// pre-processor is good performance !!

// about virtual table of implement

// performance among containers

// C++11 and C++ 14

Làm việc 3 năm, thấy cũng nên rành mấy cái này. Vì nó quan trọng cho các dự án chuyên nghiệp hơn.

1 / Mẫu kiến tạo.

Mẫu Abstract Factory

Mẫu Factory Method

Mẫu Prototype và Singleton và Builder

2 . Mẫu Cấu Trúc

Mẫu Adapter Patterns và Bridge Patterns và Proxy

Mẫu Composite Patterns và Decorator Patterns

Mẫu Flyweight Patterns và Facade Patterns

3. Mẫu Hành Vi

Mẫu Chain of Responsibility và Command Pattern

Mẫu Interpreter Patterns và Iterator Patterns và Mediator Patterns

Mẫu Memento Patterns và Observer Patterns và State Patterns

Mẫu Strategy Patterns và Template Method và Visitor Patterns

 

Strategy Patterns
Strategy là mẫu thiết kế dùng để định nghĩa một họ các thuật toán, đóng gói mỗi thuật toán đó và làm cho chúng có khả năng thay đổi dễ dàng.Strategy cho phép giả thuật tùy biến một cách độc lập tại các Client sử dụng nó.
Đơn giản thế này, tạo ra 1 đối tượng thực hiện tính đa hình từ các lớp con, từ đó thay đổi từ lớp cha, lớp con bị ảnh hưởng theo.Hết.

public abstract class FlyBehavior
    {
        public abstract void Fly();
    }
    public class FlyNoWay : FlyBehavior
    {
        public override void Fly()
        {
            Console.WriteLine("I can't fly!!");
        }
    }
    public class FlyWithRocket : FlyBehavior
    {
        public override void Fly()
        {
            Console.WriteLine("I'm flying with a rocket!!");
        }
    }
    public class FlyWithWings : FlyBehavior
    {
        public override void Fly()
        {
            Console.WriteLine("I'm flying!!");
        }
    }
    public abstract class Bird
    { 
        public FlyBehavior flyBehavior;
        public Bird() { }
        public abstract void Display();
        public void PerformFly()
        {
            flyBehavior.Fly();
        }
        public void SetFlyBehavior(FlyBehavior fb)
        {
            this.flyBehavior = fb;
        }
    }
    public class Pigeon : Bird
    {
        public Pigeon()
        {
            flyBehavior = new FlyWithWings();
        }
        public override void Display()
        {
            Console.WriteLine("I'm a Pigeon!");
        }
    }
    public class Eagle : Bird
    {
        public Eagle()
        {
            flyBehavior = new FlyWithWings();
        }
        public override void Display()
        {
            Console.WriteLine("I'm an Eagle!");
        }
    }
    public class Peguin : Bird
    {
        public Peguin()
        {
            flyBehavior = new FlyNoWay();
        }
        public override void Display()
        {
            Console.WriteLine("I'm a Peguin!");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Bird eagle = new Eagle();
            eagle.Display();
            eagle.PerformFly();
            Bird peguin = new Peguin();
            peguin.Display();
            peguin.PerformFly();
            peguin.SetFlyBehavior(new FlyWithRocket());
            peguin.PerformFly();
            Console.Read();

        }
    }

Mẫu Template Method
Là một mẫu thiết kế thuộc nhóm hành vi. Ý định của mẫu là tạo ra 1 bộ khung của một thuật toán, nhưng ủy thác việc cài đặt một vài bước trong thuật toán đó cho các lớp con. Vì thế, nó cho phép thay đổi một vài bước cụ thể trong thuật toán mà không cần thay đổi cấu trúc của thuật toán
Dễ hiểu thôi, ta cứ tạo ra các hàm ảo, rồi các lớp con xử lý hết trơn, khỏi quan tâm gì hết.

Visitor Patterns
Visitor là mẩu thiết kế(Design Patterns) cho phép định nghĩa các thao tác(operations) trên một tập hợp các đối tượng (objects) không đồng nhất (về kiểu) mà không làm thay đổi định nghĩa về lớp(classes) của các đối tượng đó. Để đạt được điều này, trong mẩu thiết kế visitor ta định nghĩa các thao tác trên các lớp tách biệt gọi các lớp visitors, các lớp này cho phép tách rời các thao tác với các đối tượng mà nó tác động đến. Với mỗi thao tác được thêm vào, một lớp visitor tương ứng được tạo ra.

interface Visitor {
    public void visit(Wheel wheel);
    public void visit(Engine engine);
    public void visit(Body body);
    public void visit(Car car);
}

//differing from above displayed UML: Additional use of an interface 'Element'
interface Element {
    public void accept(Visitor visitor);
}

/* Concrete element */
class Wheel implements Element {
    private String name;
    Wheel(String name) {
        this.name = name;
    }
    String getName() {
        return this.name;
    }
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

/* Concrete element */
class Engine implements Element{
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

/* Concrete element */
class Body implements Element{
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

/* Concrete element */
class Car implements Element {
    private Engine  engine = new Engine();
    private Body    body   = new Body();
    private Wheel[] wheels 
        = { new Wheel("front left"), new Wheel("front right"),
            new Wheel("back left"), new Wheel("back right")  };
    public void accept(Visitor visitor) {
        visitor.visit(this);
        engine.accept(visitor);
        body.accept(visitor);
        for(int i=0; i&lt;wheels.length; ++i)
            wheels[i].accept(visitor);
    }
}

/* Concrete visior */
class PrintVisitor implements Visitor {
    public void visit(Wheel wheel) {
        System.out.println("Visiting "+wheel.getName()
                            +" wheel");
    }
    public void visit(Engine engine) {
        System.out.println("Visiting engine");
    }
    public void visit(Body body) {
        System.out.println("Visiting body");
    }
    public void visit(Car car) {
        System.out.println("Visiting car");
    }
}

public class VisitorDemo {
    public static void main(String[] args){
        Car car = new Car();
        Visitor visitor = new PrintVisitor();
        car.accept(visitor);
    }
}

 

Memento Patterns
Memento là mẫu thiết kế có thể lưu lại trạng thái của một đối tượng để khôi phục lại sau này mà không vi phạm nguyên tắc đóng gói.
Tức là mẫu này giống mẫu Chain of Responsibility Patterns, tuy nhiên ko cho biết action state mà cứ đẩy hết vào đó rồi xử lý luôn.
Ví dụ :

class Originator {
    private String state;
    // The class could also contain additional data that is not part of the
    // state saved in the memento..

    public void set(String state) {
        System.out.println("Originator: Setting state to " + state);
        this.state = state;
    }

    public Memento saveToMemento() {
        System.out.println("Originator: Saving to Memento.");
        return new Memento(this.state);
    }

    public void restoreFromMemento(Memento memento) {
        this.state = memento.getSavedState();
        System.out.println("Originator: State after restoring from Memento: " + state);
    }

    public static class Memento {
        private final String state;

        public Memento(String stateToSave) {
            state = stateToSave;
        }

        public String getSavedState() {
            return state;
        }
    }
}

class Caretaker {
    public static void main(String[] args) {
        List&lt;Originator.Memento&gt; savedStates = new ArrayList&lt;Originator.Memento&gt;();

        Originator originator = new Originator();
        originator.set("State1");
        originator.set("State2");
        savedStates.add(originator.saveToMemento());
        originator.set("State3");
        // We can request multiple mementos, and choose which one to roll back to.
        savedStates.add(originator.saveToMemento());
        originator.set("State4");

        originator.restoreFromMemento(savedStates.get(1));   
    }
}

Observer Patterns
Observer định nghĩa một phụ thuộc 1- nhiều giữa các đối tượng để khi một đối tượng thay đổi trạng thái thì tất cả các phục thuộc của nó được nhận biết và cập nhật tự động.
Mẫu này có ý tưởng tương tự Mediator Patterns nhưng khác chỗ là sẽ có 1 lớp Notification để bắn callback cho các thành phần implement chứ ko phải các thành phần implement bắn cho nhau.
State Patterns
State là mẫu thiết kế cho phép một đối tượng thay đổi các hành vi của nó khi các trạng thái bên trong của nó thay đổi. Đối tượng sẽ xuất hiện để thay đổi các lớp của nó.
Cài đặt thì đơn giản thôi, tạo ra 1 hàm ảo ChangeNextState để đưa vào đó đối tượng tiếp theo rồi từ đó hành xử tiếp.

abstract class GState
    {
        public virtual void Init(Game game) { }
        public virtual void Run(Game game) { }
        public virtual void Exit(Game game) { }
        protected virtual void ChangeNextState(Game game) { }
    }

 

Interpreter Patterns
Interpreter đưa ra một ngôn ngữ, xây dựng cách diễn đạt ngôn ngữ đó cùng với một trình phiên dịch sử dụng cách diễn tả trên để phiên dịch các câu.
Đưa ra 1 loạt các ngữ cảnh rồi put vào lớp Interpreter , nó sẽ tính toán lần lượt các thành phần bằng cách đưa từng thành phần vào để nó kiểm tra với context ban đầu.

ví dụ :

Design Pattern – Interpreter

Iterator Patterns
Mẫu Iterator cung cấp khả năng truy cập và duyệt các thành phần của một tập hợp không cần quan tâm đến cách thức biểu diễn bên trong.
Giống iterator trong std container mà thôi. Không có gì đặc sắc. Mẫu này ko có ứng dụng gì nhiều.

Mediator Patterns
Mediator dùng để đóng gói cách thức tương tác của một tập hợp các đối tượng. Giảm bớt liên kết và cho phép thay đổi cách thức tương tác giữa các đối tượng
Mẫu này hay, dùng để làm notification rất tốt.

Ý tưởng, dùng 1 đối tượng Mediator chung cho các đối tượng sender giao tiếp với nhau thông qua nó. Nó sẽ để sẵn 1 hàm callback để bất kể từ đâu gọi thì nó sẽ active hàm đó , hàm đó sẽ được nằm trong thẳng cái method của class sender đó luôn. Như thế các sender có thể tự do giao tiếp với nhau qua cái Mediator này.

namespace MediatorExample {
    class Mediator {
        public delegate void ProcessMessage(String name, String message);
        public ProcessMessage callback;

        public void Handle(String name, String message) {
            callback(name, message);
        }
    }

    class Colleagues {
        private Mediator mediator;
        private String colleagueName;

        public Colleagues(Mediator mediator, String name) {
            this.mediator = mediator;
            this.mediator.callback += Receive;
            this.colleagueName = name;
        }

        public void Send(String message) {
            mediator.Handle(colleagueName, message);
        }

        private void Receive(String name, String message) {
            if (name != colleagueName)
                Console.WriteLine(name + " says to " +
                        colleagueName + ": \t\t" + message);
        }
    }

    class Program {
        public static void Main() {
            Mediator Yahoo = new Mediator();
            Colleagues John = new Colleagues(Yahoo, "John");
            Colleagues Tom = new Colleagues(Yahoo, "Tom");
            Colleagues Bill = new Colleagues(Yahoo, "Bill");
            John.Send("I think UIT Idol is great"); Console.WriteLine();

            Tom.Send("Wow, me too, i like it"); Console.WriteLine();

            John.Send("Have you SMS-ed yet"); Console.WriteLine();

            Tom.Send("Oh, not yet, too many beatiful girls, confusing"); Console.WriteLine();

            Bill.Send("Hey John and Tom, long time no see, kool huh !"); Console.WriteLine();
        }
    }
}

 

Chain of Responsibility
Là một mẫu thiết kế giải quyết cho việc thực hiện 1 chuỗi các tác vụ có trình tự mà mỗi 1 tác vụ trong chuỗi đó được đảm nhiệm bởi 1 class.

abstract class Process  
 {  
   private Process _nextProcess;  
   protected abstract void RunNext();  
   public void Run()  
   {  
      RunNext();  
      if(_nextProcess != null)  
      {  
        _nextProcess.Run();  
      }  
   }  
   public void SetNextProcess(Process process)  
   {  
      _nextProcess = process;  
   }  
 }  
 class FirstProcess : Process  
 {  
   Protect override void RunNext()  
   {  
     System.Threading.Thread.Sleep(1000);  
   }  
 }  
 class SecondProcess: Process  
 {  
   Protect override void RunNext()  
   {  
     System.Threading.Thread.Sleep(2000);  
   }  
 }  
 class ThirdProcess: Process  
 {  
   Protect override void RunNext()  
   {  
     System.Threading.Thread.Sleep(3000);  
   }  
 }  
 Process firstProcess = new FirstProcess();  
 Process secondProcess = new SecondProcess();  
 Process thirdProcess = new ThirdProcess();  
 firstProcess.SetNextProcess(secondProcess);  
 secondProcess.SetNextProcess(thirdProcess);  
 thirdProcess.SetNextProcess(null);  
 firstProcess.Run();  	
 

Command Pattern :
Mẫu này dùng để lưu trữ lại các thao tác đối tượng như 1 history vậy. Ví dụ ta có 1 loạt action, khi ta muốn undo lại thì lục từ history ra mà xử lý.

 //invoker  
 class DocumentInvoker  
 {  
      private ArrayList _commands = new ArrayList();  
      private Document _doc = new Document();  
      public void Redo(int level)  
      {  
           Console.WriteLine("---- Redo {0} level", level);  
           ((Command) _commands[level]).Redo();  
      }  
      public void Undo(int level)  
      {  
           Console.WriteLine("---- Undo {0} level", level);  
           ((Command) _commands[level]).Undo();  
      }  
      public void Write(string text)  
      {  
           DocumentEditCommand cmd = new DocumentEditCommand(_doc, text);  
           _command.Add(cmd);  
      }  
      public string Read()  
      {  
           return _doc.ReadDocument();  
      }  
 }  

 //concrete implementation  
 class DocumentEditCommand : Command  
 {  
      private Document _editableDoc;  
      private string _text;  
      public DocumentEditCommand(Document doc, string text)  
      {  
           _editableDoc = doc;  
           _text = text;  
           _editableDoc.Write(_text);  
      }  
      override public void Redo()  
      {  
           _editableDoc.Write(_text);  
      }  
      override public void Undo()  
      {  
           _editableDoc.Erase(_text);  
      }  
 }