栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

设计模式—Java

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

设计模式—Java

  • 创建型模式:单例模式、工厂模式、原型模式
  • 结构型模式:代理模式、装饰器模式
  • 行为型模式:模板方法模式、责任链模式、观察者模式
  • J2EE模式:MVC模式

单例模式
  1. 单例类只能有一个实例
  2. 单例类必须自己创建自己的唯一实例
  3. 单例类必须给所有其他对象提供这一实例

创建一个Singleton类

// SingleObject.java
public class SingleObject {
    // 创建 SingleObejct 的一个对象
    private static SingleObject instance = new SingleObject();

    // 让构造函数为 private,这样该类就不会被实例化
    private SingleObject(){}

    // 获取唯一可用的对象
    public static SingleObject getInstance() {
        return instance;
    }
    
    public void showMessage() {
        System.out.println("Hello Singleton!");
    }
}

从Singleton类获取唯一对象

// SingletonPatternDemo.java
public class SingletonPatternDemo {
    public static void main(String[] args) {
        // 不合法的构造函数,编译时报错:构造函数SingleObject()是不可见的
        // SingleObject object = new SingleObject();

        // 获取唯一可用的对象
        SingleObject object1 = SingleObject.getInstance();
        SingleObject object2 = SingleObject.getInstance();

        System.out.println(object1);    // 地址一致,为同一个对象
        System.out.println(object2);    // 地址一致,为同一个对象

    }
}

1. 懒汉式,线程安全(get方法加synchronized)
  • 优点:第一次调用才进行初始化,避免内存浪费。
  • 缺点:必须加锁synchronized才能保证单例,但加锁会影响效率。
public class Singleton1 {

    private static Singleton1 instance;

    private Singleton1() {}

    public static synchronized Singleton1 getInstance() {
        if (instance == null) {
            instance =  new Singleton1();
        }
        return instance;
    }
    
} 

2. 饿汉式
  • 优点:没有加锁,执行效率会提高
  • 缺点:类加载时就初始化,浪费内存。容易产生垃圾对象。
public class Singleton2 {

    private static Singleton2 instance = new Singleton2();

    private Singleton2() {}

    public static Singleton2 getInstance() {
        return instance;
    }
} 

3. 双检锁/双重校验锁(DCL,double-checked locking)
  • 优点:多线程安全,并且保持高性能
  • 缺点:实现较复杂
public class Singleton3 {
    private static Singleton3 instance;

    private Singleton3(){}

    public static Singleton3 getInstance() {
        if (instance == null) {
            synchronized (Singleton3.class) {
                if (instance == null) {
                    instance = new Singleton3();
                }
            }
        }
        return instance;
    }
}

工厂模式

建立一个工厂类,对实现了同一接口的一些类进行实例的创建

  • 优点:提供专门的工厂类用于创建对象。调用者只关心产品的接口,不需要了解具体的实现。
  • 缺点:每增加一个产品都要增加一个具体类和对象实现工厂,系统复杂度比较高。增加了具体类的依赖。

抽象类实现
// 抽象类--咖啡
public abstract class Coffee {
    public abstract String getName();
}

// 美式咖啡
public class Americano extends Coffee {
    @Override
    public String getName() {
        return "美式咖啡";
    }
}

// 卡布奇诺
public class Cappuccino extends Coffee {
    @Override
    public String getName() {
        return "卡布奇诺";
    }
}

接口实现
public interface Fruit{
    public void eat();    //吃水果
}

// 苹果类
class Apple implements Fruit{
    public void eat() {
        System.out.println("吃苹果");
    }
}

// 香蕉类
class Banana implements Fruit{
    public void eat(){
        System.out.println("吃香蕉");
    }
}

// 测试调用
public class Factory{
    public static void main(String[] args) {
        Fruit fruit = new Apple();
        fruit.eat();    // 吃苹果
    }
}

代理模式

使用代理对象来代替真实对象,在不修改原目标对象的前提下,提供源对象的功能,同时还具备扩展目标对象的功能特性。

静态代理

静态代理实现步骤:

  1. 定义一个借口及其实现类
  2. 创建一个代理类同样实现这个接口
  3. 将目标对象注入进代理类,然后在代理类的对应方法调用目标类中的对应方法
// 1. 定义发送资料接口
public interface MaterialService {
    String send(String message);
}

// 2. 定义发送资料接口实现类(被代理对象)
public class MaterialServiceImpl implements MaterialService {
    @Override
    public String send(String message) {
        System.out.println("send message:" + message);
        return message;
    }
}

// 3. 定义代理类并同样实现发送资料接口(代理对象)
public class MaterialProxy implements MaterialService {
    private final MaterialServiceImpl materialService;

    public MaterialProxy(MaterialServiceImpl materialService) {
        this.materialService = materialService;
    }

    @Override
    public String send(String message) {
        // 调用方法之前,添加自己的操作
        System.out.println("调用方法前,自己添加了操作");
        materialService.send(message);
        // 调用方法之后,添加自己的操作
        System.out.println("调用方法后,自己添加了操作");
        return message;
    }
}

动态代理
// 1.定义发送资料接口
public interface MaterialService {
    String send(String message);
}

// 2.定义发送资料接口实现类(被代理对象)
public class MaterialSeriveImpl implements MaterialService {
    @Override
    public String send(String message) {
        System.out.println("send message" + message);
        return message;
    }
}

// 3.定义一个JDK动态代理类
public class MaterialProxy implements InvocationHandler {
    private final MaterialServiceImpl materialService;

    public MaterialProxy(MaterialServiceImpl materialService) {
        this.materialService = materialService;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 调用方法前,添加自己的操作
        System.out.println("调用方法前操作");
        Object result = method.invoke(materialService, args);
        // 调用方法后,添加自己的操作
        System.out.println("调用方法后操作");
        return result;
    }
}

// 4. 实际使用
public class TestProxy {
    public static void main(String[] args) {
        MatericalServiceImpl target = new MaterialServiceImpl();
        MatericalService materialService = (MaterialService)Proxy.newProxyInstance(
            target.getClass().getClassLoader(),    // 目标类的类加载
            target.getClass().getInterfaces(),    // 代理需要实现的接口,可指定多个
            new MaterialProxy(target));    // 代理对象对应的自定义 InvocationHandler
        materialService.send("java");
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1028952.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号