结构型设计模式
结构型设计模式主要关注如何将类或对象组合成更大的结构,以便在保持结构灵活性和高效性的同时,实现新的功能。结构型设计模式包括以下几种:
适配器模式(Adapter Pattern)
桥接模式(Bridge Pattern)
组合模式(Composite Pattern)
装饰器模式(Decorator Pattern)
外观模式(Facade Pattern)
享元模式(Flyweight Pattern)
代理模式(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)评论