程序员必备的十大技能(进阶版)之设计模式与架构思维(二)

简介: 教程来源 https://vrhyh.cn/ 结构型模式关注类与对象的组合组织,提升系统灵活性与可维护性。含适配器(兼容接口)、装饰器(动态增强)、代理(控制访问)、外观(简化子系统)、组合(树形结构)五种核心模式,均通过封装、委托与抽象实现松耦合设计。

三、结构型模式:对象的组合与组织

结构型模式关注如何将类和对象组合成更大的结构,在保证灵活性的同时优化系统结构。

3.1 适配器模式(Adapter)—— 兼容旧系统
适配器模式将不兼容的接口转换为客户端期望的接口。

// 已有接口(第三方库)
public interface LegacyPaymentGateway {
    void sendPayment(String data);
}

public class LegacyPayPalGateway implements LegacyPaymentGateway {
    @Override
    public void sendPayment(String data) {
        System.out.println("Legacy PayPal payment: " + data);
    }
}

// 新系统期望的接口
public interface ModernPaymentGateway {
    PaymentResponse processPayment(PaymentRequest request);
}

public class PaymentRequest {
    private String orderId;
    private BigDecimal amount;
    private String cardNumber;
    // getters/setters
}

public class PaymentResponse {
    private boolean success;
    private String transactionId;
    private String message;
}

// 适配器
public class PayPalAdapter implements ModernPaymentGateway {
    private final LegacyPaymentGateway legacyGateway;

    public PayPalAdapter(LegacyPaymentGateway legacyGateway) {
        this.legacyGateway = legacyGateway;
    }

    @Override
    public PaymentResponse processPayment(PaymentRequest request) {
        // 转换请求格式
        String legacyData = String.format("order=%s,amount=%s,card=%s",
            request.getOrderId(),
            request.getAmount(),
            request.getCardNumber()
        );

        // 调用旧系统
        legacyGateway.sendPayment(legacyData);

        // 转换响应格式
        PaymentResponse response = new PaymentResponse();
        response.setSuccess(true);
        response.setTransactionId(generateTransactionId());
        response.setMessage("Payment successful");
        return response;
    }

    private String generateTransactionId() {
        return "TXN-" + System.currentTimeMillis();
    }
}

// 使用示例
public class PaymentService {
    private final ModernPaymentGateway paymentGateway;

    public PaymentService(ModernPaymentGateway paymentGateway) {
        this.paymentGateway = paymentGateway;
    }

    public void checkout() {
        PaymentRequest request = new PaymentRequest();
        request.setOrderId("ORDER-123");
        request.setAmount(new BigDecimal("99.99"));
        request.setCardNumber("****-****-****-1234");

        PaymentResponse response = paymentGateway.processPayment(request);
        System.out.println("Payment result: " + response.isSuccess());
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        LegacyPaymentGateway legacyGateway = new LegacyPayPalGateway();
        ModernPaymentGateway adapter = new PayPalAdapter(legacyGateway);
        PaymentService service = new PaymentService(adapter);
        service.checkout();
    }
}

3.2 装饰器模式(Decorator)—— 动态增强功能
装饰器模式动态地为对象添加额外职责,比继承更灵活。

// 基础组件接口
public interface Coffee {
    String getDescription();
    double getCost();
}

// 具体组件
public class SimpleCoffee implements Coffee {
    @Override
    public String getDescription() {
        return "Simple coffee";
    }

    @Override
    public double getCost() {
        return 2.0;
    }
}

// 装饰器基类
public 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();
    }
}

// 具体装饰器
public class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String getDescription() {
        return super.getDescription() + ", milk";
    }

    @Override
    public double getCost() {
        return super.getCost() + 0.5;
    }
}

public class SugarDecorator extends CoffeeDecorator {
    public SugarDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String getDescription() {
        return super.getDescription() + ", sugar";
    }

    @Override
    public double getCost() {
        return super.getCost() + 0.2;
    }
}

public class WhipDecorator extends CoffeeDecorator {
    public WhipDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String getDescription() {
        return super.getDescription() + ", whipped cream";
    }

    @Override
    public double getCost() {
        return super.getCost() + 0.8;
    }
}

// 使用示例(Java I/O 中大量使用装饰器模式)
public class CoffeeShop {
    public static void main(String[] args) {
        // 简单咖啡
        Coffee coffee = new SimpleCoffee();
        System.out.println(coffee.getDescription() + " $" + coffee.getCost());

        // 加牛奶
        coffee = new MilkDecorator(coffee);
        System.out.println(coffee.getDescription() + " $" + coffee.getCost());

        // 加糖和奶油
        coffee = new SugarDecorator(coffee);
        coffee = new WhipDecorator(coffee);
        System.out.println(coffee.getDescription() + " $" + coffee.getCost());

        // 输出:
        // Simple coffee $2.0
        // Simple coffee, milk $2.5
        // Simple coffee, milk, sugar, whipped cream $3.5
    }
}

// Java I/O 中的装饰器模式
// InputStream 是抽象组件
// FileInputStream 是具体组件
// BufferedInputStream 是装饰器
InputStream in = new BufferedInputStream(
    new GZIPInputStream(
        new FileInputStream("test.txt")
    )
);

3.3 代理模式(Proxy)—— 控制访问
代理模式为其他对象提供一种代理以控制对这个对象的访问。

// 主题接口
public interface Image {
    void display();
}

// 真实主题(高开销对象)
public class HighResolutionImage implements Image {
    private String filename;

    public HighResolutionImage(String filename) {
        this.filename = filename;
        loadFromDisk();
    }

    private void loadFromDisk() {
        System.out.println("Loading high-res image: " + filename);
        try {
            Thread.sleep(2000); // 模拟耗时加载
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void display() {
        System.out.println("Displaying high-res image: " + filename);
    }
}

// 代理
public class ImageProxy implements Image {
    private HighResolutionImage realImage;
    private String filename;

    public ImageProxy(String filename) {
        this.filename = filename;
    }

    @Override
    public void display() {
        // 延迟加载:只有在真正需要时才创建真实对象
        if (realImage == null) {
            realImage = new HighResolutionImage(filename);
        }
        realImage.display();
    }
}

// 动态代理示例(AOP实现)
public class DynamicProxyDemo {

    // 需要代理的接口
    public interface UserService {
        void saveUser(String name);
        String getUser(Long id);
    }

    // 目标对象
    public static class UserServiceImpl implements UserService {
        @Override
        public void saveUser(String name) {
            System.out.println("Saving user: " + name);
        }

        @Override
        public String getUser(Long id) {
            System.out.println("Getting user: " + id);
            return "User-" + id;
        }
    }

    // 动态代理处理器
    public static class LoggingInvocationHandler implements InvocationHandler {
        private final Object target;

        public LoggingInvocationHandler(Object target) {
            this.target = target;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 前置增强
            System.out.println("[LOG] Method " + method.getName() + " started");
            long startTime = System.currentTimeMillis();

            // 调用目标方法
            Object result = method.invoke(target, args);

            // 后置增强
            long endTime = System.currentTimeMillis();
            System.out.println("[LOG] Method " + method.getName() + " completed in " + (endTime - startTime) + "ms");

            return result;
        }
    }

    public static void main(String[] args) {
        UserService target = new UserServiceImpl();
        UserService proxy = (UserService) Proxy.newProxyInstance(
            UserService.class.getClassLoader(),
            new Class[]{UserService.class},
            new LoggingInvocationHandler(target)
        );

        proxy.saveUser("Alice");
        proxy.getUser(123L);
    }
}

3.4 外观模式(Facade)—— 简化复杂子系统
外观模式为子系统中的一组接口提供一个统一的入口。

// 复杂的子系统
public class InventorySystem {
    public boolean checkStock(String productId, int quantity) {
        System.out.println("Checking stock for: " + productId);
        return quantity <= 100;
    }

    public void reserveStock(String productId, int quantity) {
        System.out.println("Reserving " + quantity + " of " + productId);
    }
}

public class PaymentSystem {
    public boolean processPayment(String userId, BigDecimal amount) {
        System.out.println("Processing payment for user " + userId + ": $" + amount);
        return true;
    }

    public void refund(String transactionId, BigDecimal amount) {
        System.out.println("Refunding $" + amount + " for transaction: " + transactionId);
    }
}

public class ShippingSystem {
    public String createShipment(String orderId, String address) {
        System.out.println("Creating shipment for order: " + orderId);
        return "TRACK-" + orderId;
    }

    public void notifyShipping(String trackingNumber) {
        System.out.println("Sending shipping notification: " + trackingNumber);
    }
}

// 外观类
public class OrderFacade {
    private final InventorySystem inventory;
    private final PaymentSystem payment;
    private final ShippingSystem shipping;

    public OrderFacade() {
        this.inventory = new InventorySystem();
        this.payment = new PaymentSystem();
        this.shipping = new ShippingSystem();
    }

    // 简化的下单接口
    public OrderResult placeOrder(OrderRequest request) {
        try {
            // 1. 检查库存
            if (!inventory.checkStock(request.getProductId(), request.getQuantity())) {
                return OrderResult.failure("Insufficient stock");
            }

            // 2. 处理支付
            if (!payment.processPayment(request.getUserId(), request.getAmount())) {
                return OrderResult.failure("Payment failed");
            }

            // 3. 扣减库存
            inventory.reserveStock(request.getProductId(), request.getQuantity());

            // 4. 创建物流
            String trackingNumber = shipping.createShipment(
                request.getOrderId(), 
                request.getShippingAddress()
            );

            // 5. 发送通知
            shipping.notifyShipping(trackingNumber);

            return OrderResult.success(trackingNumber);

        } catch (Exception e) {
            return OrderResult.failure(e.getMessage());
        }
    }
}

// 客户端只需调用外观
public class Client {
    public static void main(String[] args) {
        OrderFacade facade = new OrderFacade();

        OrderRequest request = new OrderRequest();
        request.setOrderId("ORD-001");
        request.setUserId("USER-123");
        request.setProductId("P001");
        request.setQuantity(2);
        request.setAmount(new BigDecimal("199.98"));
        request.setShippingAddress("123 Main St");

        OrderResult result = facade.placeOrder(request);
        System.out.println("Order result: " + result.getMessage());
    }
}

3.5 组合模式(Composite)—— 树形结构处理
组合模式将对象组合成树形结构以表示“部分-整体”层次结构。

// 抽象组件
public interface FileSystemNode {
    String getName();
    long getSize();
    void display(String indent);
}

// 叶子节点(文件)
public class File implements FileSystemNode {
    private String name;
    private long size;

    public File(String name, long size) {
        this.name = name;
        this.size = size;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public long getSize() {
        return size;
    }

    @Override
    public void display(String indent) {
        System.out.println(indent + "📄 " + name + " (" + size + " bytes)");
    }
}

// 容器节点(目录)
public class Directory implements FileSystemNode {
    private String name;
    private List<FileSystemNode> children = new ArrayList<>();

    public Directory(String name) {
        this.name = name;
    }

    public void addNode(FileSystemNode node) {
        children.add(node);
    }

    public void removeNode(FileSystemNode node) {
        children.remove(node);
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public long getSize() {
        return children.stream()
            .mapToLong(FileSystemNode::getSize)
            .sum();
    }

    @Override
    public void display(String indent) {
        System.out.println(indent + "📁 " + name + " (" + getSize() + " bytes)");
        for (FileSystemNode child : children) {
            child.display(indent + "  ");
        }
    }
}

// 使用示例
public class FileSystemDemo {
    public static void main(String[] args) {
        // 构建树形结构
        Directory root = new Directory("root");

        Directory documents = new Directory("documents");
        documents.addNode(new File("resume.pdf", 102400));
        documents.addNode(new File("cover-letter.docx", 51200));

        Directory photos = new Directory("photos");
        photos.addNode(new File("vacation.jpg", 2048000));
        photos.addNode(new File("family.png", 3072000));

        Directory work = new Directory("work");
        work.addNode(new File("report.xlsx", 153600));
        work.addNode(new File("presentation.pptx", 256000));
        photos.addNode(work);

        root.addNode(documents);
        root.addNode(photos);
        root.addNode(new File("readme.txt", 1024));

        // 统一处理
        root.display("");

        // 输出:
        // 📁 root (5738624 bytes)
        //   📁 documents (153600 bytes)
        //     📄 resume.pdf (102400 bytes)
        //     📄 cover-letter.docx (51200 bytes)
        //   📁 photos (5120000 bytes)
        //     📄 vacation.jpg (2048000 bytes)
        //     📄 family.png (3072000 bytes)
        //     📁 work (409600 bytes)
        //       📄 report.xlsx (153600 bytes)
        //       📄 presentation.pptx (256000 bytes)
        //   📄 readme.txt (1024 bytes)
    }
}

来源:
https://bgnno.cn/

相关文章
|
3月前
|
运维 Java 测试技术
程序员必备的十大技能(进阶版)之性能调优与故障排查(四)
教程来源 https://aescc.cn/ 本节系统介绍Java应用性能分析与稳定性保障核心实践:涵盖Arthas诊断、火焰图性能剖析、全链路压测方法论及JMeter实战、混沌工程故障注入(ChaosBlade),并复盘Full GC与数据库死锁两大典型故障案例,助力高效定位与解决线上性能问题。
|
3月前
|
Prometheus 监控 Cloud Native
MySQL 性能监控实战:从零搭建 Prometheus + Grafana 监控告警体系(附排查 SOP)
数据库小学妹带你从零学监控!本文详解MySQL五大核心指标维度(资源、连接、查询、InnoDB、主从),手把手配置PMM/Prometheus+Grafana监控栈,设置关键告警规则,并提供SQL快照脚本与三步排障SOP。新手友好,即装即用,让性能问题无所遁形!
|
3月前
|
PyTorch API 调度
在 AMD ROCm DSW 上跑通 DeepSeek-V4-Flash:vLLM 兼容部署、长上下文验证与 8K 性能扫参
本文记录一次在 ModelScope DSW AMD GPU/ROCm 环境中部署 DeepSeek-V4-Flash 的工程实践:通过 vLLM、ROCm/AITER/PyTorch fallback 与兼容补丁建立可复现 baseline,并用短问答、2K/8K/32K needle retrieval 和 8K top-k 扫参验证正确性与性能边界。
938 1
在 AMD ROCm DSW 上跑通 DeepSeek-V4-Flash:vLLM 兼容部署、长上下文验证与 8K 性能扫参
|
3月前
|
人工智能 机器人 Shell
【开源】龙虾人工智能 —— 完全本地化的机器人大脑!不联网、不付 API 费、能看能说能理解!
龙虾本地化AI(Lobster AI)是一款完全离线、零成本、零隐私泄露的开源机器人系统,支持文本推理(Gemma4)、多模态视觉理解(桌面/摄像头)、语音识别与合成(Sherpa-ONNX),纯本地运行,不依赖任何云服务。
612 2
【开源】龙虾人工智能 —— 完全本地化的机器人大脑!不联网、不付 API 费、能看能说能理解!
|
3月前
|
人工智能 前端开发 安全
周一上线|1M 上下文成标配,GPT-5.5 更会干活;Google 拟最高 400 亿美元加码 Anthropic
先看模型这边,沉寂 15 个月后,DeepSeek 终于发布了 V4 预览版,而且照例开源。最猛的是,它直接把 1M 上下文做成了标配,量大管饱。OpenAI 那边,比 DeepSeek 早一天发布的 GPT-5.5,主打“更人性化”,在带起一众模型“稳稳接住”“懂你所想”的风潮之后,这回 GPT-5.5 不弯不绕,反倒显得清新脱俗。当然,模型的重点还是能力:Agentic Coding、Computer Use 和复杂任务处理,GPT-5.5 较之前版本都有很大提升。
1179 1
周一上线|1M 上下文成标配,GPT-5.5 更会干活;Google 拟最高 400 亿美元加码 Anthropic
|
3月前
|
人工智能 前端开发 安全
编程实测:杀疯了的 GPT-5.5 真的有它说的那么强么?
4月24日凌晨,OpenAI发布GPT-5.5——迄今最智能、易用的旗舰模型。聚焦Agentic能力,全面升级编程(Terminal-Bench达82.7%)、知识工作、科研协作、百万级长上下文(1M token)、推理效率与安全防护,已超越Claude Opus 4.7和Gemini 3.1 Pro。
744 0
编程实测:杀疯了的 GPT-5.5 真的有它说的那么强么?
|
3月前
|
存储 SQL 安全
【Java并发编程】JMM Java内存模型:原子性、可见性、有序性、happens-before原则(附《思维导图》+《面试高频考点清单》)
Java内存模型(JMM)是Java并发编程的基石,抽象定义主内存与线程工作内存的交互规则,系统解决可见性、原子性、有序性三大核心问题,并通过happens-before、volatile、synchronized等机制保障多线程安全与跨平台一致性。
|
3月前
|
Java 程序员 测试技术
程序员必备的十大技能(进阶版)之网络与高并发原理(五)
教程来源 https://tmywi.cn/ 本节系统讲解高并发场景下的操作系统与JVM深度调优:涵盖Linux网络内核参数(BBR拥塞控制、缓冲区、连接队列)、进程资源限制、JVM G1GC优化及性能压测与瓶颈定位方法,并以百万级WebSocket推送系统为实战案例,体现无锁化、异步非阻塞等高性能设计原则。
|
3月前
|
人工智能 JSON API
告别信息焦虑!用 n8n + AI 打造专属「AI 情报员」
告别信息焦虑,让 AI 帮你每天"读"完 30+ 媒体,只推送最有价值的 20 条!
434 0
告别信息焦虑!用 n8n + AI 打造专属「AI 情报员」
|
4月前
|
前端开发 JavaScript 程序员
初级程序员必备的十大技能之开发工具熟练使用(三)
教程来源 https://bncne.cn/ 浏览器开发者工具是前端调试核心利器,涵盖Elements(实时编辑DOM/CSS)、Console(日志、断点、DOM操作)、Sources(多类型断点与作用域调试)、Network(请求分析与模拟)、Performance(性能指标与火焰图)及Application(存储管理)六大面板,全面提升开发效率。