Java学习------设计模式(1)

        设计模式是软件开发中针对常见问题的可重用解决方案,是最佳实践的总结。其分为3大类:

        创建型模式;其关注对象创建机制,主要有单例,工厂方法,抽象工厂,建造者,原型这五种;

        结构型模式:以处理类和对象的组合为主,主要有适配器,桥接,组合,装饰器,外观,享元,代理这七种;

        行为型模式:主要关注对象间的通信,有责任链,命令,解释器,迭代器,中介者,备忘录,观察者,状态,策略,模板方法,访问者这11种。

        但不管是哪一种设计模式,其核心目的都是为了减少代码复用,提升代码的可维护性和可扩展性,实现代码的标准化,吸收成功的经验,避免出现以前出现过的错误,实现最佳实践。本文就单例,抽象工厂,适配器,代理这四个设计模式详细展开。

        单例模式是最简单设计模式之一,这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象,也就是说不能使用new关键字来创建对象。其核心特性主要有3:



public class EagerSingleton {//饿汉式
    // 类加载时就初始化
    private static final EagerSingleton INSTANCE = new EagerSingleton();
    
    // 私有构造器
    private EagerSingleton() {}
    
    public static EagerSingleton getInstance() {
        return INSTANCE;
    }
}//此模式线程安全,但是可能造成资源浪费

public class UnsafeLazySingleton {//懒汉式(基础版本)
    private static UnsafeLazySingleton instance;
    
    private UnsafeLazySingleton() {}
    
    public static UnsafeLazySingleton getInstance() {
        if (instance == null) {
            instance = new UnsafeLazySingleton();
        }
        return instance;
    }
}//此模式线程不安全

public class SynchronizedLazySingleton {//懒汉式(采用同步方式)
    private static SynchronizedLazySingleton instance;
    
    private SynchronizedLazySingleton() {}
    
    public static synchronized SynchronizedLazySingleton getInstance() {
        if (instance == null) {
            instance = new SynchronizedLazySingleton();
        }
        return instance;
    }
}//此模式线程安全但是效率较低

        抽象工厂模式是最常用的创建型设计模式,它提供了一种创建相关或依赖对象族的接口,而无需指定它们的具体类。其主要有4大部分:

        抽象工厂:声明创建产品族中各个产品的方法

        具体工厂:实现抽象工厂接口,创建具体产品

        抽象产品:声明产品接口

        具体产品:实现抽象产品接口的具体类

        其主要关注的是可以生产的产品族(如a族,b族,c族等),可以轻松的添加和切换生产的产品族,

// 产品A接口
interface ProductA {
    void use();
}

// 产品B接口
interface ProductB {
    void operate();
}




//具体实现
// 产品A的型号1
class ProductA1 implements ProductA {
    @Override
    public void use() {
        System.out.println("使用A1型产品");
    }
}

// 产品A的型号2
class ProductA2 implements ProductA {
    @Override
    public void use() {
        System.out.println("使用A2型产品");
    }
}

// 产品B的型号1
class ProductB1 implements ProductB {
    @Override
    public void operate() {
        System.out.println("操作B1型产品");
    }
}

// 产品B的型号2
class ProductB2 implements ProductB {
    @Override
    public void operate() {
        System.out.println("操作B2型产品");
    }
}
//定义抽象工厂接口
interface AbstractFactory {
    ProductA createProductA();
    ProductB createProductB();
}
//实现具体工厂
// 生产第一套产品(A1+B1)
class Factory1 implements AbstractFactory {
    @Override
    public ProductA createProductA() {
        return new ProductA1();
    }

    @Override
    public ProductB createProductB() {
        return new ProductB1();
    }
}

// 生产第二套产品(A2+B2)
class Factory2 implements AbstractFactory {
    @Override
    public ProductA createProductA() {
        return new ProductA2();
    }

    @Override
    public ProductB createProductB() {
        return new ProductB2();
    }
}
//客户端使用
public class Client {
    public static void main(String[] args) {
        // 使用第一套工厂生产产品
        AbstractFactory factory1 = new Factory1();
        ProductA a1 = factory1.createProductA();
        ProductB b1 = factory1.createProductB();
        
        a1.use();      // 输出: 使用A1型产品
        b1.operate();  // 输出: 操作B1型产品

        System.out.println("------");
        
        // 使用第二套工厂生产产品
        AbstractFactory factory2 = new Factory2();
        ProductA a2 = factory2.createProductA();
        ProductB b2 = factory2.createProductB();
        
        a2.use();      // 输出: 使用A2型产品
        b2.operate();  // 输出: 操作B2型产品
    }
}

        适配器模式是一种结构型设计模式,它允许不兼容的接口能够一起工作。适配器模式就像现实世界中的电源适配器,让不同规格的插头能够插入插座。其通过包装对象的方式,将一个类的接口转换成客户端期望的另一个接口,从而使原本因接口不兼容而无法一起工作的类可以协同工作。

        适配器模式主要有三种角色:

                       目标接口:客户端期望的接口

                       适配者:需要被适配的现有类

                       适配器:包装适配者并实现目标接口

        其实现代码如下:

//类适配器(通过继承实现)
// 目标接口
interface Target {
    void request();
}

// 需要适配的类
class Adaptee {
    public void specificRequest() {
        System.out.println("Adaptee的特殊请求");
    }
}

// 类适配器(继承Adaptee并实现Target)
class ClassAdapter extends Adaptee implements Target {
    @Override
    public void request() {
        specificRequest(); // 调用父类方法
    }
}

// 客户端使用
public class Client {
    public static void main(String[] args) {
        Target target = new ClassAdapter();
        target.request(); // 输出: Adaptee的特殊请求
    }
}



//对象适配器(通过组合实现)
// 目标接口
interface Target {
    void request();
}

// 需要适配的类
class Adaptee {
    public void specificRequest() {
        System.out.println("Adaptee的特殊请求");
    }
}

// 对象适配器(组合Adaptee并实现Target)
class ObjectAdapter implements Target {
    private Adaptee adaptee;
    
    public ObjectAdapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }
    
    @Override
    public void request() {
        adaptee.specificRequest();
    }
}

// 客户端使用
public class Client {
    public static void main(String[] args) {
        Adaptee adaptee = new Adaptee();
        Target target = new ObjectAdapter(adaptee);
        target.request(); // 输出: Adaptee的特殊请求
    }
}

        其优点众多,包括复用性强,可以实现多个不兼容的类一起工作,使用灵活且方便,同时还能降低程序的耦合度,遵循开闭原则,通过引入新的适配器进行适配而不是修改源代码。但是如果其会带来一些额外的开销,同时由于增加了新的类和对象,会提高程序的复杂度。

        最后是代理模式,其是一种结构型设计模式,为其他对象提供一种代理以控制对这个对象的访问。代理模式就像现实生活中的"中介",在客户端和目标对象之间起到中介作用。其主要是通过创建一个代理对象来控制对原始对象的访问,可以在不改变原始类代码的情况下,增加额外的功能或控制访问。主要实现4大功能:

        访问控制:控制对原始对象的访问权限

        功能增强:在不修改原始对象的情况下添加额外功能

        延迟初始化:推迟高开销对象的创建

        远程访问:为远程对象提供本地代表

        其主要包含3大角色,分别是:

        抽象主题:定义真实主题和代理主题的共同接口
        真实主题:实际执行业务逻辑的对象
        代理:持有真实主题的引用,控制对真实主题的访问

        其有多种实现方式,具体代码如下:

//1.静态代理
/**
 *手动编写代理类 
 *一个真实主题对应一个代理类
 *编译时确定代理关系
*/
// 抽象主题
interface Image {
    void display();
}

// 真实主题
class RealImage implements Image {
    private String filename;
    
    public RealImage(String filename) {
        this.filename = filename;
        loadFromDisk();
    }
    
    private void loadFromDisk() {
        System.out.println("加载图片: " + filename);
    }
    
    @Override
    public void display() {
        System.out.println("显示图片: " + filename);
    }
}

// 代理
class ProxyImage implements Image {
    private RealImage realImage;
    private String filename;
    
    public ProxyImage(String filename) {
        this.filename = filename;
    }
    
    @Override
    public void display() {
        if (realImage == null) {
            realImage = new RealImage(filename); // 延迟初始化
        }
        preDisplay();
        realImage.display();
        postDisplay();
    }
    
    private void preDisplay() {
        System.out.println("显示前准备工作");
    }
    
    private void postDisplay() {
        System.out.println("显示后清理工作");
    }
}

// 客户端使用
public class Client {
    public static void main(String[] args) {
        Image image = new ProxyImage("test.jpg");
        // 图片直到真正需要显示时才会加载
        image.display();
    }
}

//2.jdk动态代理

/**
 *运行时动态生成代理类
 *只能代理接口
 *通过InvocationHandler统一处理所有方法调用
*/
import java.lang.reflect.*;

// 抽象主题
interface UserService {
    void addUser(String name);
    void deleteUser(String name);
}

// 真实主题
class UserServiceImpl implements UserService {
    @Override
    public void addUser(String name) {
        System.out.println("添加用户: " + name);
    }
    
    @Override
    public void deleteUser(String name) {
        System.out.println("删除用户: " + name);
    }
}

// 调用处理器
class UserServiceInvocationHandler implements InvocationHandler {
    private Object target;
    
    public UserServiceInvocationHandler(Object target) {
        this.target = target;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("--- 开始执行 " + method.getName() + " ---");
        Object result = method.invoke(target, args);
        System.out.println("--- 结束执行 " + method.getName() + " ---");
        return result;
    }
}

// 客户端使用
public class Client {
    public static void main(String[] args) {
        UserService realService = new UserServiceImpl();
        
        UserService proxy = (UserService) Proxy.newProxyInstance(
            UserService.class.getClassLoader(),
            new Class[]{UserService.class},
            new UserServiceInvocationHandler(realService)
        );
        
        proxy.addUser("张三");
        proxy.deleteUser("李四");
    }
}

//3.CGLIB动态代理
/**
 *通过继承方式实现代理
 *可以代理普通类(不需要接口)
 *性能通常比JDK动态代理好
 *不能代理final类和方法
 */
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

// 真实主题(不需要实现接口)
class ProductService {
    public void addProduct(String name) {
        System.out.println("添加产品: " + name);
    }
    
    public void deleteProduct(String name) {
        System.out.println("删除产品: " + name);
    }
}

// 方法拦截器
class ProductServiceInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println(">>> 调用前: " + method.getName());
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("<<< 调用后: " + method.getName());
        return result;
    }
}

// 客户端使用
public class Client {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(ProductService.class);
        enhancer.setCallback(new ProductServiceInterceptor());
        
        ProductService proxy = (ProductService) enhancer.create();
        
        proxy.addProduct("手机");
        proxy.deleteProduct("电脑");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值