结构型设计模式

January 09, 2025 作者: southern 分类: 浏览: 13 评论: 0

结构型设计模式主要关注如何将类或对象组合成更大的结构,以便在保持结构灵活性和高效性的同时,实现新的功能。结构型设计模式包括以下几种:

  1. 适配器模式(Adapter Pattern)

  2. 桥接模式(Bridge Pattern)

  3. 组合模式(Composite Pattern)

  4. 装饰器模式(Decorator Pattern)

  5. 外观模式(Facade Pattern)

  6. 享元模式(Flyweight Pattern)

  7. 代理模式(Proxy Pattern)


1. 适配器模式

适配器模式就像一个电源适配器,它允许你将不同国家的插头插入到本国的插座中。适配器充当中间人,使得不兼容的接口能够协同工作。

适配器模式将一个类的接口转换成客户期望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作。

// 目标接口
interface Target {
    void request();
}
​
// 需要适配的类
class Adaptee {
    public void specificRequest() {
        System.out.println("Specific request.");
    }
}
​
// 适配器类
class Adapter implements Target {
    private Adaptee adaptee;
​
    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }
​
    @Override
    public void request() {
        adaptee.specificRequest();
    }
}
​
// 使用适配器模式
public class Main {
    public static void main(String[] args) {
        Adaptee adaptee = new Adaptee();
        Target target = new Adapter(adaptee);
        target.request();  // 输出: Specific request.
    }
}

2. 桥接模式

桥接模式就像是一个遥控器和电视之间的关系。遥控器是抽象部分,电视是实现部分。你可以通过不同的遥控器控制不同的电视,而不需要改变遥控器或电视的内部结构。

桥接模式将抽象部分与它的实现部分分离,使它们都可以独立地变化。

// 实现部分接口
interface TV {
    void on();
    void off();
}
​
// 具体实现
class SonyTV implements TV {
    @Override
    public void on() {
        System.out.println("Sony TV is on.");
    }
​
    @Override
    public void off() {
        System.out.println("Sony TV is off.");
    }
}
​
class SamsungTV implements TV {
    @Override
    public void on() {
        System.out.println("Samsung TV is on.");
    }
​
    @Override
    public void off() {
        System.out.println("Samsung TV is off.");
    }
}
​
// 抽象部分
abstract class RemoteControl {
    protected TV tv;
​
    public RemoteControl(TV tv) {
        this.tv = tv;
    }
​
    public abstract void turnOn();
    public abstract void turnOff();
}
​
// 具体抽象
class BasicRemoteControl extends RemoteControl {
    public BasicRemoteControl(TV tv) {
        super(tv);
    }
​
    @Override
    public void turnOn() {
        tv.on();
    }
​
    @Override
    public void turnOff() {
        tv.off();
    }
}
​
// 使用桥接模式
public class Main {
    public static void main(String[] args) {
        TV sonyTV = new SonyTV();
        RemoteControl remote = new BasicRemoteControl(sonyTV);
        remote.turnOn();  // 输出: Sony TV is on.
        remote.turnOff(); // 输出: Sony TV is off.
​
        TV samsungTV = new SamsungTV();
        remote = new BasicRemoteControl(samsungTV);
        remote.turnOn();  // 输出: Samsung TV is on.
        remote.turnOff(); // 输出: Samsung TV is off.
    }
}

3. 组合模式

组合模式就像是一个公司的组织结构。公司由多个部门组成,每个部门又由多个员工组成。你可以对整个公司、某个部门或某个员工执行相同的操作,比如计算工资。

组合模式将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。

import java.util.ArrayList;
import java.util.List;
​
// 组件接口
interface Employee {
    void showDetails();
}
​
// 叶子节点
class Developer implements Employee {
    private String name;
​
    public Developer(String name) {
        this.name = name;
    }
​
    @Override
    public void showDetails() {
        System.out.println("Developer: " + name);
    }
}
​
class Manager implements Employee {
    private String name;
​
    public Manager(String name) {
        this.name = name;
    }
​
    @Override
    public void showDetails() {
        System.out.println("Manager: " + name);
    }
}
​
// 组合节点
class Department implements Employee {
    private String name;
    private List<Employee> employees = new ArrayList<>();
​
    public Department(String name) {
        this.name = name;
    }
​
    public void addEmployee(Employee employee) {
        employees.add(employee);
    }
​
    @Override
    public void showDetails() {
        System.out.println("Department: " + name);
        for (Employee employee : employees) {
            employee.showDetails();
        }
    }
}
​
// 使用组合模式
public class Main {
    public static void main(String[] args) {
        Employee dev1 = new Developer("John");
        Employee dev2 = new Developer("Jane");
        Employee manager = new Manager("Alice");
​
        Department engineering = new Department("Engineering");
        engineering.addEmployee(dev1);
        engineering.addEmployee(dev2);
        engineering.addEmployee(manager);
​
        engineering.showDetails();
        // 输出:
        // Department: Engineering
        // Developer: John
        // Developer: Jane
        // Manager: Alice
    }
}

4. 装饰器模式

装饰器模式就像是为咖啡添加调料。你可以先点一杯普通的咖啡,然后根据需要添加牛奶、糖、奶油等调料,而不需要改变咖啡的基本结构。

装饰器模式动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器模式相比生成子类更为灵活。

// 组件接口
interface Coffee {
    String getDescription();
    double getCost();
}
​
// 具体组件
class SimpleCoffee implements Coffee {
    @Override
    public String getDescription() {
        return "Simple Coffee";
    }
​
    @Override
    public double getCost() {
        return 5.0;
    }
}
​
// 装饰器抽象类
abstract class CoffeeDecorator implements Coffee {
    protected Coffee decoratedCoffee;
​
    public CoffeeDecorator(Coffee coffee) {
        this.decoratedCoffee = coffee;
    }
​
    @Override
    public String getDescription() {
        return decoratedCoffee.getDescription();
    }
​
    @Override
    public double getCost() {
        return decoratedCoffee.getCost();
    }
}
​
// 具体装饰器
class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }
​
    @Override
    public String getDescription() {
        return decoratedCoffee.getDescription() + ", Milk";
    }
​
    @Override
    public double getCost() {
        return decoratedCoffee.getCost() + 1.5;
    }
}
​
class SugarDecorator extends CoffeeDecorator {
    public SugarDecorator(Coffee coffee) {
        super(coffee);
    }
​
    @Override
    public String getDescription() {
        return decoratedCoffee.getDescription() + ", Sugar";
    }
​
    @Override
    public double getCost() {
        return decoratedCoffee.getCost() + 0.5;
    }
}
​
// 使用装饰器模式
public class Main {
    public static void main(String[] args) {
        Coffee coffee = new SimpleCoffee();
        System.out.println(coffee.getDescription() + " $" + coffee.getCost());  // 输出: Simple Coffee $5.0
​
        coffee = new MilkDecorator(coffee);
        System.out.println(coffee.getDescription() + " $" + coffee.getCost());  // 输出: Simple Coffee, Milk $6.5
​
        coffee = new SugarDecorator(coffee);
        System.out.println(coffee.getDescription() + " $" + coffee.getCost());  // 输出: Simple Coffee, Milk, Sugar $7.0
    }
}

5. 外观模式

外观模式就像是一个酒店的前台。你不需要知道酒店内部的复杂运作(如客房服务、餐饮服务、清洁服务等),只需要通过前台就可以完成所有的需求。

外观模式为子系统中的一组接口提供了一个统一的接口,使得子系统更容易使用。

// 子系统类
class RoomService {
    public void bookRoom() {
        System.out.println("Room booked.");
    }
}
​
class RestaurantService {
    public void orderFood() {
        System.out.println("Food ordered.");
    }
}
​
class CleaningService {
    public void cleanRoom() {
        System.out.println("Room cleaned.");
    }
}
​
// 外观类
class HotelFacade {
    private RoomService roomService;
    private RestaurantService restaurantService;
    private CleaningService cleaningService;
​
    public HotelFacade() {
        this.roomService = new RoomService();
        this.restaurantService = new RestaurantService();
        this.cleaningService = new CleaningService();
    }
​
    public void bookRoomAndOrderFood() {
        roomService.bookRoom();
        restaurantService.orderFood();
    }
​
    public void cleanRoom() {
        cleaningService.cleanRoom();
    }
}
​
// 使用外观模式
public class Main {
    public static void main(String[] args) {
        HotelFacade hotelFacade = new HotelFacade();
        hotelFacade.bookRoomAndOrderFood();  // 输出: Room booked. \n Food ordered.
        hotelFacade.cleanRoom();             // 输出: Room cleaned.
    }
}

6. 享元模式

享元模式就像是一个字库系统。每个字符(如字母、数字)只需要存储一次,然后在需要时重复使用,而不是每次都创建一个新的字符对象。

享元模式通过共享技术有效地支持大量细粒度的对象,以减少内存占用和提高性能。

import java.util.HashMap;
import java.util.Map;
​
// 享元接口
interface Character {
    void display();
}
​
// 具体享元
class ConcreteCharacter implements Character {
    private char symbol;
​
    public ConcreteCharacter(char symbol) {
        this.symbol = symbol;
    }
​
    @Override
    public void display() {
        System.out.println("Character: " + symbol);
    }
}
​
// 享元工厂
class CharacterFactory {
    private Map<Character, ConcreteCharacter> characters = new HashMap<>();
​
    public Character getCharacter(char symbol) {
        if (!characters.containsKey(symbol)) {
            characters.put(symbol, new ConcreteCharacter(symbol));
        }
        return characters.get(symbol);
    }
}
​
// 使用享元模式
public class Main {
    public static void main(String[] args) {
        CharacterFactory factory = new CharacterFactory();
​
        Character a = factory.getCharacter('A');
        a.display();  // 输出: Character: A
​
        Character b = factory.getCharacter('B');
        b.display();  // 输出: Character: B
​
        Character a2 = factory.getCharacter('A');
        a2.display(); // 输出: Character: A
    }
}

7. 代理模式

代理模式就像是一个房产中介。你不需要直接与房主沟通,而是通过中介来完成租房或买房的过程。

代理模式为其他对象提供一个代理,并控制对原对象的访问。

// 主题接口
interface House {
    void rent();
}
​
// 真实主题
class RealHouse implements House {
    @Override
    public void rent() {
        System.out.println("Renting the house.");
    }
}
​
// 代理类
class HouseProxy implements House {
    private RealHouse realHouse;
​
    @Override
    public void rent() {
        if (realHouse == null) {
            realHouse = new RealHouse();
        }
        System.out.println("Proxy is handling the rental process.");
        realHouse.rent();
    }
}
​
// 使用代理模式
public class Main {
    public static void main(String[] args) {
        House house = new HouseProxy();
        house.rent();  // 输出: Proxy is handling the rental process. \n Renting the house.
    }
}

#2025(6)

评论