Mô Hình Singleton Mô hình Singleton đảm bảo rằng một lớp chỉ có một thể hiện duy nhất. Bạn không thể tạo mới một đối tượng từ lớp này vì constructor được khai báo là private. Thông thường, bạn sử dụng phương thức getInstance() để lấy thể hiện của lớp.
Dưới đây là cách cơ bản để triển khai mô hình Singleton:
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
Có nhiều cách khác nhau để triển khai mô hình Singleton, bao gồm:
- Lazy Initialization (Thread-safe):
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
- Eager Initialization:
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
- Static Inner Class:
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton() {}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
- Enum:
public enum Singleton {
INSTANCE;
public void whateverMethod() {}
}
- Double-Checked Locking:
public class Singleton {
private volatile static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
Mô Hình Observer Mô hình Observer định nghĩa một phụ thuộc một-nhiều giữa các đối tượng. Khi trạng thái của một đối tượng thay đổi, tất cả các đối tượng phụ thuộc sẽ được thông báo và cập nhật tự động.
Dưới đây là ví dụ về cách triển khai mô hình Observer:
public interface Person {
void getMessage(String s);
}
public class LaoWang implements Person {
private String name = "Lao Wang";
@Override
public void getMessage(String s) {
System.out.println(name + " received a message: " + s);
}
}
public class LaoLi implements Person {
private String name = "Lao Li";
@Override
public void getMessage(String s) {
System.out.println(name + " received a message: " + s);
}
}
public class XiaoMei {
List<Person> list = new ArrayList<>();
public void addPerson(Person person) {
list.add(person);
}
public void notifyPerson() {
for (Person person : list) {
person.getMessage("Come and play with me!");
}
}
}
public class Test {
public static void main(String[] args) {
XiaoMei xiaoMei = new XiaoMei();
LaoWang laoWang = new LaoWang();
LaoLi laoLi = new LaoLi();
xiaoMei.addPerson(laoWang);
xiaoMei.addPerson(laoLi);
xiaoMei.notifyPerson();
}
}
Mô Hình Decorator Mô hình Decorator cho phép bạn thêm hành vi hoặc chức năng vào một đối tượng mà không cần thay đổi cấu trúc của nó. Ví dụ, trong Java, IO Stream sử dụng mô hình Decorator.
Dưới đây là một ví dụ về cách triển khai mô hình Decorator:
public abstract class Food {
public abstract String make();
}
public class Bread extends Food {
private Food basicFood;
public Bread(Food basicFood) {
this.basicFood = basicFood;
}
@Override
public String make() {
return basicFood.make() + "+ Bread";
}
}
public class Cream extends Food {
private Food basicFood;
public Cream(Food basicFood) {
this.basicFood = basicFood;
}
@Override
public String make() {
return basicFood.make() + "+ Cream";
}
}
public class Vegetable extends Food {
private Food basicFood;
public Vegetable(Food basicFood) {
this.basicFood = basicFood;
}
@Override
public String make() {
return basicFood.make() + "+ Vegetable";
}
}
public class Test {
public static void main(String[] args) {
Food food = new Bread(new Vegetable(new Cream(new Food() {
@Override
public String make() {
return "Sausage";
}
})));
System.out.println(food.make());
}
}
Mô Hình Adapter Mô hình Adapter cho phép các đối tượng với giao diện không tương thích làm việc cùng nhau bằng cách đóng gói chúng trong một lớp adapter.
Dưới đây là một ví dụ về cách triển khai mô hình Adapter:
public class Phone {
public static final int V = 220; // Normal voltage 220V
private VoltageAdapter adapter;
public void setAdapter(VoltageAdapter adapter) {
this.adapter = adapter;
}
public void charge() {
adapter.changeVoltage();
}
}
class VoltageAdapter {
public void changeVoltage() {
System.out.println("Charging...");
System.out.println("Original voltage: " + Phone.V + "V");
System.out.println("Converted voltage: " + (Phone.V - 200) + "V");
}
}
public class Test {
public static void main(String[] args) {
Phone phone = new Phone();
VoltageAdapter adapter = new VoltageAdapter();
phone.setAdapter(adapter);
phone.charge();
}
}
Mô Hình Factory Mô hình Factory cung cấp một cách để tạo ra các đối tượng mà không cần chỉ định lớp cụ thể. Có ba loại chính: Simple Factory, Factory Method, và Abstract Factory.
Simple Factory:
abstract class Car {
public abstract void run();
public abstract void stop();
}
class Benz extends Car {
@Override
public void run() {
System.out.println("Benz is starting...");
}
@Override
public void stop() {
System.out.println("Benz is stopping...");
}
}
class Ford extends Car {
@Override
public void run() {
System.out.println("Ford is starting...");
}
@Override
public void stop() {
System.out.println("Ford is stopping...");
}
}
class Factory {
public static Car getCarInstance(String type) {
if ("Benz".equals(type)) {
return new Benz();
} else if ("Ford".equals(type)) {
return new Ford();
}
return null;
}
}
public class Test {
public static void main(String[] args) {
Car car = Factory.getCarInstance("Benz");
if (car != null) {
car.run();
car.stop();
} else {
System.out.println("Cannot create this car...");
}
}
}
Factory Method:
public interface Moveable {
void run();
}
public class Plane implements Moveable {
@Override
public void run() {
System.out.println("Plane is running...");
}
}
public class Broom implements Moveable {
@Override
public void run() {
System.out.println("Broom is running...");
}
}
public abstract class VehicleFactory {
public abstract Moveable create();
}
public class PlaneFactory extends VehicleFactory {
@Override
public Moveable create() {
return new Plane();
}
}
public class BroomFactory extends VehicleFactory {
@Override
public Moveable create() {
return new Broom();
}
}
public class Test {
public static void main(String[] args) {
VehicleFactory factory = new BroomFactory();
Moveable m = factory.create();
m.run();
}
}
Abstract Factory:
public abstract class AbstractFactory {
public abstract Vehicle createVehicle();
public abstract Weapon createWeapon();
public abstract Food createFood();
}
public class DefaultFactory extends AbstractFactory {
@Override
public Vehicle createVehicle() {
return new Car();
}
@Override
public Weapon createWeapon() {
return new AK47();
}
@Override
public Food createFood() {
return new Apple();
}
}
public class Test {
public static void main(String[] args) {
AbstractFactory f = new DefaultFactory();
Vehicle v = f.createVehicle();
v.run();
Weapon w = f.createWeapon();
w.shoot();
Food a = f.createFood();
a.printName();
}
}
Mô Hình Proxy Mô hình Proxy cung cấp một lớp đại diện cho một đối tượng khác. Có hai loại chính: Static Proxy và Dynamic Proxy.
Static Proxy:
public interface ProxyInterface {
void marry();
}
public class WeddingCompany implements ProxyInterface {
private ProxyInterface proxyInterface;
public WeddingCompany(ProxyInterface proxyInterface) {
this.proxyInterface = proxyInterface;
}
@Override
public void marry() {
System.out.println("We are the wedding company.");
System.out.println("Preparing for the wedding...");
System.out.println("Rehearsing the program...");
System.out.println("Buying gifts...");
System.out.println("Assigning staff...");
System.out.println("The wedding can start now.");
proxyInterface.marry();
System.out.println("The wedding is over. We will handle the rest.");
}
}
public class NormalHome implements ProxyInterface {
@Override
public void marry() {
System.out.println("We are getting married!");
}
}
public class Test {
public static void main(String[] args) {
ProxyInterface proxyInterface = new WeddingCompany(new NormalHome());
proxyInterface.marry();
}
}
Mô Hình Producer/Consumer Mô hình Producer/Consumer xử lý vấn đề sản xuất và tiêu thụ dữ liệu. Một module chịu trách nhiệm tạo dữ liệu, trong khi module khác xử lý dữ liệu. Module tạo dữ liệu được gọi là Producer, và module xử lý dữ liệu được gọi là Consumer.
Dưới đây là một ví dụ về cách triển khai mô hình Producer/Consumer:
public class SyncStack {
private String[] str = new String[10];
private int index;
public synchronized void push(String sst) {
if (index == str.length) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify();
str[index] = sst;
index++;
}
public synchronized String pop() {
if (index == 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify();
index--;
return str[index];
}
}
public class Producter implements Runnable {
private SyncStack stack;
public Producter(SyncStack stack) {
this.stack = stack;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
String product = "Product " + i;
stack.push(product);
System.out.println("Produced: " + product);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Consumer implements Runnable {
private SyncStack stack;
public Consumer(SyncStack stack) {
this.stack = stack;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
String product = stack.pop();
System.out.println("Consumed: " + product);
try {
Thread.sleep(400);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class TestDemo {
public static void main(String[] args) {
SyncStack stack = new SyncStack();
Consumer consumer = new Consumer(stack);
Producter producer = new Producter(stack);
new Thread(consumer).start();
new Thread(producer).start();
}
}