Factory Pattern
Được chia làm 2 loại: Factory Method và Abstract Factory.
1. Factory method:
Định nghĩa 1 interface cho việc tạo đối tượng, nhưng để các lớp con quyết định lớp nào sẽ được tạo. “Factory method” giao việc khởi tạo đối tượng cụ thể cho lớp con.

Chúng ta có 1 class là ShapeFactory, cần class này tạo ra các hình vẽ theo yêu cầu, mà không cần quan tâm nó sẽ dùng phương pháp hay cách thức nào. Đây là mục đích của Factory Method.
Cách thực hiện:
- Đầu tiên tạo 1 interface hoặc abstract class, đặt tên là Shape, với phương thức draw() để vẽ ra 1 hình.
- Tiếp theo là tạo ra các subclass kế thừa hoặc implement interface Shape, các class này sẽ override phương thức
draw(). Ví dụ class Circle, Square, Rectangle. - Thực hiện Factory Method bằng cách tạo ra
ShapeFactory:
class ShapeFactory
{
public function getShape($type) {
switch ($type) {
case "square":
return new Square;
break;
case "circle":
return new Circle;
break;
default:
return null;
break;
}
return null;
}
}
// tạo hình tròn:
$factory = new ShapeFactory();
$circle = $factory->getShape("circle");
$circle->draw();Như vậy muốn vẽ hình tròn hay hình vuông ta chỉ cần thay đổi giá trị của $type trong getShape(). Sau đó chỉ cần gọi hàm draw(), không cần quan tâm hàm này thực hiện bằng cách nào, “Factory” sẽ cung cấp điều chính xác mà chúng ta mong muốn.
2. Abstract Factory Pattern:
Là thiết kế giúp cung cấp 1 lớp giao diện (interface) có chức năng tạo ra một tập hợp các đối tượng liên quan hoặc phụ thuộc lẫn nhau mà không chỉ ra đó là những lớp cụ thể nào tại thời điểm thiết kế. Abstract Factory đóng gói 1 nhóm những lớp “Factory” trong ứng dụng, đây là những lớp được dùng để tạo lập đối tượng (object). Các lớp “Factory” này có chung một giao diện được kế thừa từ 1 lớp cha gọi là “lớp sản xuất ảo”.
Có thể hiểu đơn giản Abstract Factory như 1 siêu nhà máy dùng để tạo ra các “Factory” khác.
- AbstractFactory: định nghĩa 1 giao tiếp cho các thao tác khởi tạo các “sản phẩm” ảo (AbstractProduct).
- ConcreteFactory: thực thi giao tiếp AbstractFactory để tạo ra đối tượng cụ thể.
- AbstractProduct: định nghĩa 1 lớp ảo cho một loại đối tượng “sản phẩm”.
- Product: kế thừa từ lớp “sản phẩm” ảo.
- Client: sử dụng các lớp AbstractFactory và AbstractProduct trong hệ thống.
Ví dụ:

Khác 1 chút với Factory Method, ở đây ta có thêm 1 lớp Producer có vai trò tương tự như lớp Factory ở phần 1. Đây là mô hình mở rộng của pattern Factory Method.
Bước 1: tạo interface Shape (được hiểu là AbstractProduct):
// AbstractProduct
interface Shape {
function draw();
}Bước 2: tạo class implement interface Shape (gọi là Product):
// Circle Product
class Circle implements Shape
{
public function draw() {
echo "Draw circle";
}
}
// Square Product
class Square implements Shape
{
public function draw() {
echo "Draw square";
}
}Bước 3: tạo interface Color (là AbstractProduct tương tự Shape):
interface Color {
function fill();
}Bước 4: tương tự bước 2, tạo các class Product implement interface Color:
class Red implements Color
{
public function fill() {
echo "Fill red";
}
}
class Green implements Color ...Bước 5: Tạo 1 lớp Abstract với phương thức gián tiếp đến thao tác khởi tạo các Shape và Color object (AbstractFactory):
abstract class AbstractFactory {
abstract function getColor($color);
abstract function getShape($shape);
}Bước 6: tạo lớp Factory kế thừa AbstractFactory để thực hiện generate các object cụ thể (đây gọi là ConcreteFactory):
// ShapeFactory:
class ShapeFactory extends AbstractFactory
{
public function getShape($type) {
switch ($type) {
case "square": return new Square;
case "circle": return new Circle;
}
return null;
}
}
// ColorFactory:
class ColorFactory extends AbstractFactory
{
public function getColor($color) {
switch ($color):
case "red": return new Red;
case "green": return new Green;
}
return null;
}
}Bước 7: tạo FactoryProducer để khởi tạo 1 abstract Shape/Color Factory:
class FactoryProducer
{
public static function getFactory($choice) {
if ($choice == "shape") return new ShapeFactory;
elseif ($choice == "color") return new ColorFactory;
return null;
}
}Bước 8: tạo Client để sử dụng AbstractFactory và AbstractProduct:
// include các class
include ...
// tạo ShapeFactory
$shapeFactory = FactoryProducer::getFactory("shape");
// tạo Product
$shape = $shapeFactory->getShape("circle");
$shape->draw();
// tương tự với màu sắc:
$colorFactory = FactoryProducer::getFactory("color");
$color = $colorFactory->getColor("red");
$color->fill();Mô hình tổng quát hơn:

