hocvietcode.com
  • Trang chủ
  • Học lập trình
    • Lập trình C/C++
    • Lập trình HTML
    • Lập trình Javascript
      • Javascript cơ bản
      • ReactJS framework
      • AngularJS framework
      • Typescript cơ bản
      • Angular
    • Lập trình Mobile
      • Lập Trình Dart Cơ Bản
        • Dart Flutter Framework
    • Cơ sở dữ liệu
      • MySQL – MariaDB
      • Micrsoft SQL Server
      • Extensible Markup Language (XML)
      • JSON
    • Lập trình PHP
      • Lập trình PHP cơ bản
      • Laravel Framework
    • Lập trình Java
      • Java Cơ bản
    • Cấu trúc dữ liệu và giải thuật
    • Lập Trình C# Cơ Bản
    • Machine Learning
  • WORDPRESS
    • WordPress cơ bản
    • WordPress nâng cao
    • Chia sẻ WordPress
  • Kiến thức hệ thống
    • Microsoft Azure
    • Docker
    • Linux
  • Chia sẻ IT
    • Tin học văn phòng
      • Microsoft Word
      • Microsoft Excel
    • Marketing
      • Google Adwords
      • Facebook Ads
      • Kiến thức khác
    • Chia sẻ phần mềm
    • Review công nghệ
    • Công cụ – tiện ích
      • Kiểm tra bàn phím online
      • Kiểm tra webcam online
Đăng nhập
  • Đăng nhập / Đăng ký

Please enter key search to display results.

Home
  • Phân tích thiết kế triển khai phần mềm
Thiết kế lại và Triển khai

Thiết kế lại và Triển khai

  • 28-06-2025
  • Toanngo92
  • 0 Comments

Ở bài viết trước, ta đã nghiên cứu một hệ thống quản lý phương tiện với sơ đồ lớp và logic nghiệp vụ sơ bộ.

Tuy nhiên, việc từ thiết kế chuyển sang mã nguồn thật sự không phải là con đường tuyến tính.

Trong quá trình triển khai, người phát triển thường gặp phải:

  • Các chi tiết thiết kế chưa rõ ràng
  • Những ràng buộc chưa được lường trước
  • Các vấn đề về hiệu năng, tương thích, mở rộng

→ Vì vậy, cần quay lại và thiết kế lại (redesign) trước khi tiến hành viết mã hoàn chỉnh.


Mục lục

    • 🛠️ 1.3. Hộp công cụ mở rộng – Các mẫu thiết kế
    • ♻️ 1.4. Tại sao phải thiết kế lại?
    • ⚠️ 1.5. Triển khai không đơn thuần là “viết code”
    • 💡 1.6. Từ đây, ta sẽ học gì tiếp?
  • Đánh giá thiết kế cũ và cơ hội tái cấu trúc
    • 🔍 2.1. Vì sao phải đánh giá lại thiết kế?
    • 🧱 2.2. Sơ đồ lớp hiện tại
    • ✅ Nhận xét sơ bộ:
    • 🔎 2.3. Đánh giá theo Cohesion và Coupling
    • → Cơ hội cải thiện:
    • 🔁 2.4. Khi nào nên refactor?
    • 🧠 2.5. Tư duy thiết kế lại (Redesign Thinking)
    • Các nguyên tắc cần nhớ:
    • 📌 2.6. Các lựa chọn tái thiết kế
      • 🔹 Phương án 1: Thiết kế lại theo thành phần (Component-based)
      • 🔹 Phương án 2: Áp dụng mẫu thiết kế phù hợp
    • 📎 2.7. Kết luận chương
  • Áp dụng các mẫu thiết kế
    • 🎯 3.1. Tại sao cần mẫu thiết kế?
    • 🏗️ 3.2. Mô hình MVC – Tách biệt rõ ràng giao diện và logic
      • 📌 Trong hệ thống hiện tại:
    • 🎭 3.3. Mẫu Facade – Giao diện hộp đen đơn giản hóa tương tác
      • ✅ Giải pháp:
    • 🏭 3.4. Mẫu Factory – Quản lý việc tạo đối tượng
      • ✅ Giải pháp:
    • 👁️ 3.5. Mẫu Observer – Giao tiếp tự động giữa các lớp
      • ✅ Giải pháp:
    • 🧠 3.6. Khi nào không nên dùng mẫu thiết kế?
    • ✅ 3.7. Tổng kết chương
  • Triển khai hệ thống từ thiết kế
    • 🧭 4.1. Mục tiêu của quá trình triển khai
    • 📐 4.2. Phân tích thứ tự triển khai
    • 🚗 4.3. Cài đặt lớp Vehicle
    • 🏭 4.4. Cài đặt lớp VehicleFactory
    • 🅿️ 4.5. Cài đặt lớp Garage – tập hợp các phương tiện
    • 🧑‍💼 4.6. Triển khai Facade – lớp điều phối trung tâm
    • 👁️ 4.7. Kết nối với View – định hướng Observer
    • 🔧 4.8. Ghi nhớ kỹ thuật triển khai
    • 📌 4.9. Tổng kết chương
  • Tổng kết dự án
    • 🎯 5.1. Hành trình từ thiết kế đến triển khai
    • 🧰 5.2. Các mẫu thiết kế đã áp dụng – và lý do
    • 📉 5.3. Những sai lầm thường gặp khi thiết kế và triển khai
    • ✅ 5.4. Kinh nghiệm rút ra
    • 🧭 5.5. Hướng phát triển tiếp theo
    • 📌 5.6. Tổng kết cuối cùng

🛠️ 1.3. Hộp công cụ mở rộng – Các mẫu thiết kế

Ở các chủ đề trước, bạn đã được học các mẫu thiết kế như:

  • MVC (Model–View–Controller)
  • Facade
  • Factory
  • Observer
  • Strategy
    v.v.

Chúng chính là những công cụ hữu ích giúp bạn:

  • Giảm phụ thuộc giữa các lớp (low coupling)
  • Tăng khả năng mở rộng
  • Cải thiện sự phân tách trách nhiệm

♻️ 1.4. Tại sao phải thiết kế lại?

Không phải mọi bản thiết kế ban đầu đều tốt. Khi tiến hành triển khai, chúng ta thường:

  • Phát hiện lỗ hổng logic
  • Gặp khó khăn khi viết mã
  • Nhận ra mô hình quá rối rắm hoặc quá chặt chẽ

Thiết kế lại là một bước quan trọng giữa thiết kế lý thuyết và triển khai thực tế, nhằm:

  • Tối ưu hóa kiến trúc
  • Đơn giản hóa sự phụ thuộc
  • Tận dụng mẫu thiết kế đúng lúc, đúng chỗ

⚠️ 1.5. Triển khai không đơn thuần là “viết code”

Việc triển khai cần:

  • Tư duy hệ thống: mỗi dòng code phải phù hợp với toàn bộ cấu trúc hệ thống.
  • Kỹ năng sử dụng mẫu thiết kế: lựa chọn mẫu phù hợp để code dễ mở rộng và bảo trì.
  • Biết đánh đổi: ví dụ thêm một mẫu design pattern có thể làm hệ thống linh hoạt hơn, nhưng cũng làm tăng số lượng class.

💡 1.6. Từ đây, ta sẽ học gì tiếp?

Trong các chương tiếp theo, bạn sẽ được hướng dẫn:

  • Đánh giá lại thiết kế hiện tại (sơ đồ lớp cũ)
  • Quyết định có cần thiết kế lại không
  • Áp dụng các mẫu thiết kế phù hợp
  • Viết code triển khai thực tế theo mô hình MVC
  • Phân tích cách dùng Factory, Facade, Observer trong bối cảnh cụ thể
  • Hiểu quá trình chuyển hóa từ thiết kế thành mã nguồn

✅ Ghi nhớ:
Thiết kế lại không có nghĩa là bỏ đi thiết kế cũ.
Mà là cải tiến dựa trên góc nhìn mới và trải nghiệm triển khai thực tế.

Đánh giá thiết kế cũ và cơ hội tái cấu trúc

🔍 2.1. Vì sao phải đánh giá lại thiết kế?

Sau khi có bản thiết kế sơ bộ (ví dụ: sơ đồ lớp ở Chủ đề 6), ta cần:

  • Xác định vấn đề tiềm ẩn trong thiết kế
  • Đánh giá xem có đang vi phạm các nguyên lý thiết kế như cohesion thấp hoặc coupling cao
  • Tìm kiếm cơ hội để refactor trước khi triển khai chính thức

❗ Một thiết kế không được rà soát kỹ trước khi code rất dễ tạo ra “nợ kỹ thuật”.


🧱 2.2. Sơ đồ lớp hiện tại

Thiết kế hệ thống hiện tại bao gồm các lớp như:

  • Job, Employee, Garage, Vehicle, Customer, Payroll, Organisation

Mỗi lớp đại diện cho một thực thể trong hệ thống quản lý phương tiện.

✅ Nhận xét sơ bộ:

  • Các lớp có trách nhiệm rõ ràng
  • Không trùng chức năng
  • Không chia sẻ biến toàn cục
  • → Thiết kế ổn, nhưng chưa tối ưu.

🔎 2.3. Đánh giá theo Cohesion và Coupling

Tiêu chíNhận xét
Cohesion (kết dính)Tương đối cao. Mỗi lớp đều tập trung làm đúng 1 nhiệm vụ
Coupling (phụ thuộc)Ở mức trung bình. Các lớp vẫn còn liên kết trực tiếp với nhau

→ Cơ hội cải thiện:

  • Tách biệt các module lớn để giảm liên kết
  • Ẩn chi tiết thực thi bên trong các lớp “vỏ bọc” (dùng Facade)
  • Tự động hóa việc tạo đối tượng (dùng Factory)

🔁 2.4. Khi nào nên refactor?

Dấu hiệuHành động
Một lớp có quá nhiều chức năngTách lớp
Nhiều lớp gọi trực tiếp đến nhauDùng interface hoặc mẫu Facade
Mã khởi tạo đối tượng lặp đi lặp lạiÁp dụng Factory
Thay đổi một phần làm ảnh hưởng nhiều phần khácDùng Observer để giảm liên kết

🧠 2.5. Tư duy thiết kế lại (Redesign Thinking)

“Thiết kế lại là một nghệ thuật – không có đúng tuyệt đối, nhưng có rất nhiều sai.”

Các nguyên tắc cần nhớ:

  • Không thay đổi chỉ vì “muốn sạch đẹp hơn”
  • Thiết kế lại phải giải quyết vấn đề thực tế
  • Luôn cân nhắc cái giá phải trả (phức tạp tăng lên? số lượng class tăng?)
  • Không nên lạm dụng các mẫu thiết kế

📌 2.6. Các lựa chọn tái thiết kế

🔹 Phương án 1: Thiết kế lại theo thành phần (Component-based)

  • Tách hệ thống thành các nhóm lớn:
    • Vehicle Management
    • Personnel Management
    • Customer Management

→ Ưu điểm: dễ quản lý theo mô-đun
→ Nhược điểm: tăng số lượng lớp, cohesion thấp hơn, không phù hợp với quy mô nhỏ

🔹 Phương án 2: Áp dụng mẫu thiết kế phù hợp

  • Facade: tạo lớp giao diện hộp đen giữa các module
  • Factory: xử lý logic khởi tạo phức tạp
  • Observer: cập nhật giữa model và UI

→ Phù hợp hơn cho hệ thống hiện tại


📎 2.7. Kết luận chương

  • Thiết kế cũ nhìn chung ổn định, nhưng vẫn có điểm nghẽn
  • Không nên triển khai vội nếu:
    • Có coupling cao
    • Lớp chịu nhiều trách nhiệm
    • Việc mở rộng gây ảnh hưởng nhiều nơi
  • Refactor là cách chuẩn bị để triển khai dễ dàng và hiệu quả hơn
  • Mẫu thiết kế nên được chọn dựa trên vấn đề cụ thể, không phải theo sở thích cá nhân

Áp dụng các mẫu thiết kế

🎯 3.1. Tại sao cần mẫu thiết kế?

Sau khi đánh giá lại thiết kế, ta nhận ra:

  • Một số lớp phụ thuộc trực tiếp vào nhau
  • Việc tạo đối tượng thiếu kiểm soát và lặp lại
  • Giao diện người dùng và logic nghiệp vụ chưa tách biệt

→ Đây là cơ hội để áp dụng các mẫu thiết kế (design patterns) nhằm:

  • Tăng tính mở rộng
  • Giảm phụ thuộc giữa các lớp
  • Làm rõ trách nhiệm của từng phần

🏗️ 3.2. Mô hình MVC – Tách biệt rõ ràng giao diện và logic

Thành phầnVai trò
ModelChứa dữ liệu, xử lý logic nghiệp vụ
ViewGiao diện người dùng (UI)
ControllerĐiều phối giữa View và Model

📌 Trong hệ thống hiện tại:

  • Model: đã có – gồm Vehicle, Job, Garage, Organisation…
  • View/Controller: cần thiết kế cho cả bản desktop và web (dùng chung model)

→ Ưu điểm:

  • Tăng khả năng tái sử dụng model
  • Cho phép triển khai đa giao diện

🎭 3.3. Mẫu Facade – Giao diện hộp đen đơn giản hóa tương tác

Vấn đề: Nếu các lớp frontend gọi trực tiếp vào các lớp trong model → coupling cao, khó bảo trì.

✅ Giải pháp:

Tạo một lớp trung gian gọi là Facade, ví dụ SystemGateway, chịu trách nhiệm:

  • Gọi đến các lớp con trong model
  • Cung cấp API đơn giản cho UI

→ View chỉ cần gọi SystemGateway.addVehicle(...) mà không cần biết chi tiết bên dưới là gì.


🏭 3.4. Mẫu Factory – Quản lý việc tạo đối tượng

Vấn đề: Nếu mỗi lần tạo xe đều phải new Vehicle() và cấu hình lại → trùng lặp và dễ sai.

✅ Giải pháp:

Tạo lớp VehicleFactory với phương thức getVehicle(int type)

  • Tự động trả về đối tượng Vehicle đã cấu hình đúng
  • Dễ bảo trì khi thêm loại xe mới

Ví dụ:

javaCopyEditVehicle v = VehicleFactory.getVehicle(TYPE_TRANSIT);

→ Ưu điểm:

  • Giảm lặp code
  • Dễ cấu hình, mở rộng loại phương tiện

👁️ 3.5. Mẫu Observer – Giao tiếp tự động giữa các lớp

Vấn đề: Khi dữ liệu thay đổi (Model), View không tự biết để cập nhật.

✅ Giải pháp:

  • Model có thể “thông báo” tới các View khi có thay đổi
  • Dùng interface Observer để thiết kế linh hoạt

→ Kết nối lỏng (loose coupling) giữa Model và View

Ví dụ ứng dụng:

  • Khi Garage.addVehicle(...) được gọi, View sẽ tự động cập nhật danh sách xe.

🧠 3.6. Khi nào không nên dùng mẫu thiết kế?

Tình huốngGiải pháp
Hệ thống quá nhỏKhông dùng pattern phức tạp, chỉ cần code đơn giản
Không có khả năng tái sử dụngTránh over-engineering
Quá nhiều pattern → rối rắmChỉ dùng khi có vấn đề cụ thể cần giải quyết

✅ 3.7. Tổng kết chương

Mẫu thiết kếTác dụng
MVCTách biệt UI – Logic
FacadeGiảm phụ thuộc frontend ↔ model
FactoryQuản lý việc khởi tạo đối tượng
ObserverTự động cập nhật UI khi model thay đổi

🧩 Dùng đúng pattern vào đúng chỗ là chìa khóa để hệ thống dễ bảo trì – dễ mở rộng – dễ kiểm thử.

Triển khai hệ thống từ thiết kế

🧭 4.1. Mục tiêu của quá trình triển khai

Sau khi hoàn tất thiết kế và lựa chọn các mẫu phù hợp, bước tiếp theo là viết mã nguồn (coding) cho từng thành phần của hệ thống. Việc triển khai cần:

  • Tuân thủ đúng thiết kế đã thống nhất
  • Áp dụng mẫu thiết kế vào thực tế
  • Viết code có cấu trúc, rõ ràng, dễ bảo trì

📐 4.2. Phân tích thứ tự triển khai

Triển khai nên bắt đầu từ lớp ít phụ thuộc nhất:

  1. Các lớp cơ bản như Vehicle, Job
  2. Các lớp chứa tập hợp như Garage
  3. Lớp điều phối trung tâm như Organisation
  4. Facade
  5. View / Controller

✅ Triển khai từ trong ra ngoài, từ logic sang UI


🚗 4.3. Cài đặt lớp Vehicle

Đây là lớp cơ bản đại diện cho phương tiện.

javaCopyEditpublic class Vehicle {
    private double rate;
    private int capacity;

    public void setRate(double val) { rate = val; }
    public double getRate() { return rate; }

    public void setCapacity(int val) { capacity = val; }
    public int getCapacity() { return capacity; }
}

⚙️ Lớp đơn giản, dễ test, không phụ thuộc ai


🏭 4.4. Cài đặt lớp VehicleFactory

Dùng mẫu Factory để tạo các đối tượng Vehicle theo loại.

javaCopyEditpublic class VehicleFactory {
    public static final int TYPE_TRANSIT = 0;
    public static final int TYPE_COMBO = 1;
    public static final int TYPE_BOX = 2;

    public static Vehicle getVehicle(int type) {
        double rate = 0.0;
        int capacity = 0;
        Vehicle v = new Vehicle();

        switch (type) {
            case TYPE_TRANSIT: rate = 2.0; capacity = 2000; break;
            case TYPE_COMBO:   rate = 1.5; capacity = 1000; break;
            case TYPE_BOX:     rate = 3.0; capacity = 5000; break;
            default: return null;
        }

        v.setRate(rate);
        v.setCapacity(capacity);
        return v;
    }
}

🎯 Tách riêng logic khởi tạo → dễ quản lý, dễ mở rộng


🅿️ 4.5. Cài đặt lớp Garage – tập hợp các phương tiện

javaCopyEditimport java.util.HashMap;

public class Garage {
    private HashMap<String, Vehicle> myVehicles;

    public Garage() {
        myVehicles = new HashMap<>();
    }

    public void addVehicle(String licence, int type) {
        Vehicle v = VehicleFactory.getVehicle(type);
        if (v != null) {
            myVehicles.put(licence, v);
        }
    }

    public Vehicle getVehicle(String licence) {
        return myVehicles.get(licence);
    }
}

📦 Lưu trữ phương tiện theo biển số xe.
Dùng HashMap để tra cứu nhanh.


🧑‍💼 4.6. Triển khai Facade – lớp điều phối trung tâm

javaCopyEditpublic class SystemGateway {
    private Garage garage;

    public SystemGateway() {
        garage = new Garage();
    }

    public void registerVehicle(String licence, int type) {
        garage.addVehicle(licence, type);
    }

    public Vehicle findVehicle(String licence) {
        return garage.getVehicle(licence);
    }
}

🎯 Giúp UI không cần biết Garage hay Factory, chỉ gọi SystemGateway.


👁️ 4.7. Kết nối với View – định hướng Observer

Giả sử bạn có UI JavaFX hoặc Swing:

javaCopyEditSystemGateway system = new SystemGateway();
system.registerVehicle("51A-12345", VehicleFactory.TYPE_TRANSIT);

Vehicle v = system.findVehicle("51A-12345");
System.out.println("Rate: " + v.getRate());

Nếu bạn muốn UI tự động cập nhật khi có thay đổi, có thể dùng mẫu Observer hoặc Property Binding (trong JavaFX).


🔧 4.8. Ghi nhớ kỹ thuật triển khai

BướcNội dung
1Bắt đầu từ lớp độc lập
2Cài đặt Factory để đơn giản hóa khởi tạo
3Dùng Facade để gom các tương tác phức tạp
4Tách riêng View – Model – Controller
5Viết test sớm để kiểm tra từng lớp

📌 4.9. Tổng kết chương

  • Quá trình triển khai nên đi theo thiết kế đã được cải tiến
  • Mẫu thiết kế giúp code dễ hiểu, dễ mở rộng
  • Dù viết code, ta vẫn cần tư duy thiết kế – không nên “code freestyle”

Tổng kết dự án

🎯 5.1. Hành trình từ thiết kế đến triển khai

Chúng ta đã bắt đầu với một hệ thống có sẵn thiết kế sơ bộ. Qua quá trình:

  • Đánh giá lại thiết kế để phát hiện điểm yếu (coupling cao, cohesion thấp)
  • Áp dụng mẫu thiết kế phù hợp để tối ưu kiến trúc
  • Viết mã nguồn triển khai từng lớp, từ đơn giản đến phức tạp
  • Xây dựng Facade và phân lớp rõ ràng để chuẩn bị tích hợp với UI

→ Giúp hệ thống sạch hơn, dễ mở rộng và dễ bảo trì.


🧰 5.2. Các mẫu thiết kế đã áp dụng – và lý do

Mẫu thiết kếMục đíchÁp dụng
MVCTách UI khỏi logic nghiệp vụDùng cho cả desktop & web
FacadeẨn chi tiết hệ thống, giảm phụ thuộc UILớp SystemGateway
FactoryTạo đối tượng đúng cách, không lặp codeLớp VehicleFactory
ObserverKết nối model và UI linh hoạtGợi ý dùng nếu muốn cập nhật UI tự động

🧠 Dùng design pattern đúng lúc đúng chỗ là yếu tố quyết định cho kiến trúc tốt.


📉 5.3. Những sai lầm thường gặp khi thiết kế và triển khai

Sai lầmHậu quả
Thiết kế ban đầu thiếu đánh giáGặp lỗi logic khi code
Không dùng mẫu phù hợpCode rối, khó bảo trì
Quá lạm dụng patternTăng độ phức tạp không cần thiết
Code trước, thiết kế sauKhông mở rộng được về sau

✅ 5.4. Kinh nghiệm rút ra

  • Thiết kế lại là bình thường, không phải thất bại
  • Phải luôn đánh giá lại kiến trúc trước khi viết code
  • Pattern là công cụ, không phải mục tiêu
  • Tách UI – Logic ngay từ đầu giúp tránh lỗi khó sửa
  • Code phải phản ánh đúng thiết kế, và ngược lại

🧭 5.5. Hướng phát triển tiếp theo

Sau khi đã hoàn thành quá trình thiết kế lại và triển khai hệ thống nhỏ, bạn nên tiếp tục học:

  • Viết Unit Test và TDD cho các lớp đã triển khai
  • Thiết kế lại hệ thống với yêu cầu mở rộng (thêm tính năng quản lý tài xế, phân quyền…)
  • Triển khai Web UI hoặc Mobile App dựa trên MVC
  • Học nâng cao về Domain-Driven Design, Microservices

📌 5.6. Tổng kết cuối cùng

Một thiết kế tốt không phải là thiết kế đẹp trên giấy,
mà là thiết kế có thể chuyển thành code hoạt động thực tế
và chịu được thay đổi theo thời gian.

Bài viết liên quan:

Thiết kế tình huống điển hình, thực hành và ví dụ
Bảo trì và tái cấu trúc phần mềm
Các yếu tố để thiết kế phần mềm hiệu quả
Một số mẫu thiết kế phổ biến
Mẫu thiết kế (Design Pattern)
Phân tích và thiết kế động
Phân tích và Thiết kế Tĩnh
Phân tích & Thiết kế hướng đối tượng linh hoạt (Agile Object Orientation)
Thiết kế Lấy Người Dùng Làm Trung Tâm (User Centred Design)
Giới thiệu nội dung series phân tích thiết kế và triển khai phần mềm

THÊM BÌNH LUẬN Cancel reply

Dịch vụ thiết kế Wesbite

NỘI DUNG MỚI CẬP NHẬT

3. Quản lý dự án công nghệ thông tin (IT PROJECT MANAGEMENT)

1. Giới thiệu khái niệm chuẩn mực và đạo đức nghề nghiệp trong CNTT

2. Áp dụng các chuẩn mực và đạo đức nghề nghiệp trong CNTT

Phát triển .NET Core và Tương lai.

Kiến trúc Onion trong ASP.NET Core

Giới thiệu

hocvietcode.com là website chia sẻ và cập nhật tin tức công nghệ, chia sẻ kiến thức, kỹ năng. Chúng tôi rất cảm ơn và mong muốn nhận được nhiều phản hồi để có thể phục vụ quý bạn đọc tốt hơn !

Liên hệ quảng cáo: [email protected]

Kết nối với HỌC VIẾT CODE

© hocvietcode.com - Tech888 Co .Ltd since 2019

Đăng nhập

Trở thành một phần của cộng đồng của chúng tôi!
Registration complete. Please check your email.
Đăng nhập bằng google
Đăng kýBạn quên mật khẩu?

Create an account

Welcome! Register for an account
The user name or email address is not correct.
Registration confirmation will be emailed to you.
Log in Lost your password?

Reset password

Recover your password
Password reset email has been sent.
The email could not be sent. Possible reason: your host may have disabled the mail function.
A password will be e-mailed to you.
Log in Register
×