JavaRush /Blog Java /Random-VI /Mẫu thiết kế nhà xưởng

Mẫu thiết kế nhà xưởng

Xuất bản trong nhóm
Chào bạn! Hôm nay chúng ta sẽ tiếp tục cùng các bạn nghiên cứu các mẫu thiết kế. Trong bài giảng này chúng ta sẽ nói về Nhà máy. Chúng tôi sẽ thảo luận với bạn vấn đề nào được giải quyết bằng cách sử dụng mẫu này và xem ví dụ về cách một nhà máy giúp mở quán cà phê. Và tôi cũng sẽ cung cấp cho bạn 5 bước đơn giản để tạo nhà máy. Mẫu thiết kế nhà xưởng - 1Để cùng quan điểm với mọi người và dễ dàng nắm bắt được bản chất, bạn nên làm quen với các chủ đề sau:
  • Kế thừa trong Java
  • Thu hẹp và mở rộng các loại tham chiếu trong Java
  • Tương tác giữa các lớp và đối tượng khác nhau

Nhà máy là gì?

Mẫu thiết kế Factory cho phép bạn kiểm soát việc tạo đối tượng. Quá trình tạo một đối tượng mới không đơn giản nhưng cũng không quá phức tạp. Chúng ta đều biết rằng để tạo một đối tượng mới, chúng ta phải sử dụng lớp new. Và có vẻ như không có gì phải quản lý ở đây, nhưng thực tế không phải vậy. Khó khăn có thể nảy sinh khi ứng dụng của chúng ta có một lớp nhất định có nhiều lớp con và cần phải tạo một thể hiện của một lớp nhất định tùy thuộc vào một số điều kiện. Factory là một mẫu thiết kế giúp giải quyết vấn đề tạo ra các đối tượng khác nhau tùy theo một số điều kiện. Trừu tượng phải không? Tính cụ thể và rõ ràng hơn sẽ xuất hiện khi chúng ta xem ví dụ bên dưới.

Chúng tôi tạo ra nhiều loại cà phê khác nhau

Giả sử chúng ta muốn tự động hóa một quán cà phê. Chúng ta cần học cách pha chế các loại cà phê khác nhau. Để làm điều này, trong ứng dụng của chúng tôi, chúng tôi sẽ tạo một loại cà phê và các dẫn xuất của nó: Americano, cappuccino, espresso, latte - những loại cà phê mà chúng tôi sẽ pha chế. Hãy bắt đầu với lớp cà phê chung:
public class Coffee {
    public void grindCoffee(){
        // перемалываем кофе
    }
    public void makeCoffee(){
        // делаем кофе
    }
    public void pourIntoCup(){
        // наливаем в чашку
    }
}
Tiếp theo, hãy tạo những người thừa kế của nó:
public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Khách hàng của chúng tôi sẽ gọi một số loại cà phê và thông tin này cần được chuyển đến chương trình. Điều này có thể được thực hiện theo nhiều cách khác nhau, ví dụ như sử dụng String. Nhưng nó phù hợp nhất cho những mục đích này enum. Hãy tạo enumvà xác định trong đó các loại cà phê mà chúng tôi nhận đặt hàng:
public enum CoffeeType {
    ESPRESSO,
    AMERICANO,
    CAFFE_LATTE,
    CAPPUCCINO
}
Tuyệt vời, bây giờ hãy viết mã cho quán cà phê của chúng ta:
public class CoffeeShop {

    public Coffee orderCoffee(CoffeeType type) {
        Coffee coffee = null;

        switch (type) {
            case AMERICANO:
                coffee = new Americano();
                break;
            case ESPRESSO:
                coffee = new Espresso();
                break;
            case CAPPUCCINO:
                coffee = new Cappucсino();
                break;
            case CAFFE_LATTE:
                coffee = new CaffeLatte();
                break;
        }

        coffee.grindCoffee();
        coffee.makeCoffee();
        coffee.pourIntoCup();

        System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
        return coffee;
    }
}
Phương pháp này orderCoffeecó thể được chia thành hai thành phần:
  1. switch-caseTạo một thể hiện cà phê cụ thể trong một khối Đây là nơi mà Nhà máy thực hiện việc tạo ra một loại cụ thể tùy thuộc vào các điều kiện.
  2. Bản thân việc chuẩn bị là xay, nấu và đổ vào cốc.
Điều quan trọng cần biết nếu bạn cần thay đổi phương pháp trong tương lai:
  1. Bản thân thuật toán chuẩn bị (nghiền, nấu và rót vào cốc) sẽ không thay đổi (ít nhất là chúng tôi hy vọng như vậy).
  2. Nhưng phạm vi cà phê có thể thay đổi. Có lẽ chúng ta sẽ bắt đầu làm mocha.. Mocha.. Mokkachi... Chúa phù hộ cho anh ấy, một loại cà phê mới.
Chúng ta có thể giả định rằng trong tương lai, với một mức độ xác suất nhất định, chúng ta sẽ phải thực hiện các thay đổi đối với phương thức, đối với khối switch-case. Cũng có thể trong quán cà phê của chúng tôi, phương pháp này orderCoffeesẽ không phải là nơi duy nhất chúng tôi tạo ra các loại cà phê khác nhau. Vì vậy, những thay đổi sẽ phải được thực hiện ở một số nơi. Có lẽ bạn đã hiểu điều tôi đang muốn nói. Chúng ta cần tái cấu trúc. Di chuyển khối chịu trách nhiệm tạo cà phê vào một lớp riêng vì hai lý do:
  1. Chúng tôi sẽ có thể sử dụng lại logic tạo cà phê ở những nơi khác.
  2. Nếu phạm vi thay đổi, chúng tôi sẽ không phải chỉnh sửa mã ở mọi nơi sẽ sử dụng tính năng tạo cà phê. Chỉ cần thay đổi mã ở một nơi là đủ.
Nói cách khác, đã đến lúc phải cắt giảm nhà máy.

Chúng tôi đang cưa nhà máy đầu tiên của mình

Để làm điều này, hãy tạo một lớp mới sẽ chỉ chịu trách nhiệm tạo các phiên bản cần thiết của các lớp cà phê:
public class SimpleCoffeeFactory {
    public Coffee createCoffee (CoffeeType type) {
        Coffee coffee = null;

        switch (type) {
            case AMERICANO:
                coffee = new Americano();
                break;
            case ESPRESSO:
                coffee = new Espresso();
                break;
            case CAPPUCCINO:
                coffee = new Cappucino();
                break;
            case CAFFE_LATTE:
                coffee = new CaffeLatte();
                break;
        }

        return coffee;
    }
}
Chúc mừng! Chúng ta vừa triển khai mẫu thiết kế Factory ở dạng đơn giản nhất. Mặc dù mọi thứ có thể còn đơn giản hơn nếu phương thức được đặt ở createCoffeedạng tĩnh. Nhưng khi đó chúng ta sẽ mất đi hai khả năng:
  1. Kế thừa SimpleCoffeeFactoryvà ghi đè createCoffee.
  2. Triển khai việc triển khai nhà máy được yêu cầu trong các lớp học của chúng tôi.
Nói đến việc thực hiện. Chúng ta cần quay lại quán cà phê và triển khai nhà máy pha cà phê của mình.

Đưa nhà máy vào quán cà phê

Hãy viết lại lớp quán cà phê của chúng ta bằng cách sử dụng một nhà máy:
public class CoffeeShop {

    private final SimpleCoffeeFactory coffeeFactory;

    public CoffeeShop(SimpleCoffeeFactory coffeeFactory) {
        this.coffeeFactory = coffeeFactory;
    }

    public Coffee orderCoffee(CoffeeType type) {
        Coffee coffee = coffeeFactory.createCoffee(type);
        coffee.grindCoffee();
        coffee.makeCoffee();
        coffee.pourIntoCup();

        System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
        return coffee;
    }
}
Tuyệt vời. Bây giờ chúng ta hãy thử mô tả sơ đồ và chính xác cấu trúc của mẫu thiết kế Factory.

5 bước để mở nhà máy của riêng bạn

Bước 1. Trong chương trình của bạn, bạn có một lớp với một số lớp con, như trong hình bên dưới: Mẫu Thiết Kế Nhà Xưởng - 2Bước 2. Bạn tạo một lớp enumtrong đó bạn xác định một biến enum cho mỗi lớp con:
enum CatType {
    LION,
    TIGER,
    BARSIK
}
Bước 3. Bạn xây dựng nhà máy của mình. Bạn gọi nó MyClassFactory, mã dưới đây:
class CatFactory {}
Bước 4. Bạn tạo một phương thức trong nhà máy của mình createMyClasscó biến - enum MyClassType. Mã dưới đây:
class CatFactory {
    public Cat createCat(CatType type) {

    }
}
Bước 5. Bạn viết một khối trong phần thân của phương thức switch-caseđể lặp qua tất cả các giá trị enum và tạo một thể hiện của lớp tương ứng với enumgiá trị đó:
class CatFactory {
        public Cat createCat(CatType type) {
            Cat cat = null;

            switch (type) {
                case LION:
                    cat =  new Barsik();
                    break;
                case TIGER:
                    cat = new Tiger();
                    break;
                case BARSIK:
                    cat =  new Lion();
                    break;
            }

            return cat;
        }
    }
Giống như một ông chủ.

Làm thế nào để đào tạo

Đọc đã tốt, viết code còn tốt hơn. Nếu tên của bạn có số chữ cái chẵn, hãy thử tạo tiệm bánh pizza ảo của riêng bạn. Nếu tên của bạn có số lượng chữ cái lẻ, hãy thử tạo một thanh sushi ảo. Nếu bạn ẩn danh, bạn là người may mắn. Hôm nay bạn có thể nghỉ ngơi.
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION