java----------开发模式

开发模式

Java 中一般认为有23种设计模式,当然暂时不需要所有的都会,但是其中常见的几种设计模式应该去掌握。

【一】总体来说设计模式分为三大类:

创建型模式,共五种:

  • 工厂方法模式
  • 抽象工厂模式
  • 单例模式
  • 建造者模式
  • 原型模式。

结构型模式,共七种:

  • 适配器模式
  • 装饰器模式
  • 代理模式
  • 外观模式
  • 桥接模式
  • 组合模式
  • 享元模式。

行为型模式,共十一种:

  • 策略模式
  • 模板方法模式
  • 观察者模式
  • 迭代子模式
  • 责任链模式
  • 命令模式
  • 备忘录模式
  • 状态模式
  • 访问者模式
  • 中介者模式
  • 解释器模式。

【二】单例模式

所谓的单例设计指的是一个类只允许产生一个实例化对象。 最好理解的一种设计模式,分为懒汉式饿汉式

  • 1、饿汉式:构造方法私有化,外部无法产生新的实例化对象,只能通过static方法取得实例化对象
class Singleton {
    private static Singleton instance = new Singleton();
    private Singleton() {
    }
    public static Singleton getInstance() {
        return instance;
	}
}

  • 2、懒汉式:当第一次去使用Singleton对象的时候才会为其产生实例化对象的操作
class Singleton {
    private static volatile Singleton singleton = null;
    private Singleton() {
    }
    //双重检验
    public static Singleton getInstance() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

当多个线程并发执行 getInstance 方法时,懒汉式会存在线程安全问题,所以用到了 synchronized 来实现线程的同步,当一个线程获得锁的时候其他线程就只能在外等待其执行完毕。

【三】工厂设计模式

1、静态工厂方法模式
将上面的多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可

interface Sender {
    void Send();
}

class MailSender implements Sender {
    @Override
    public void Send() {
        System.out.println("This is mail sender...");
    }
}

class SmsSender implements Sender {
    @Override
    public void Send() {
        System.out.println("This is sms sender...");
    }
}
//静态工厂
class SendFactory {
    public static Sender produceMail() {
        return new MailSender();
    }
    public static Sender produceSms() {
        return new SmsSender();
    }
}

【四】代理模式

代理模式指给一个对象提供一个代理对象,并由代理对象控制对原对象的引用。代理可以分为静态代理动态代理
1、静态代理

interface IService {
    void service();
}

class Service implements IService{
    @Override
    public void service() {
        System.out.println("被代理对象执行相关操作");
    }
}

class ProxyService implements IService{
    private IService service;
    public ProxyService() {
        this.service = new Service();
    }
    public ProxyService(IService service) {
        this.service = service;
    }

    @Override
    public void service() {
        System.out.println("开始执行service()方法");
        service.service();
        System.out.println("service()方法执行完毕");
    }
}

2、动态代理

  • JDK动态代理:
    创建动态代理对象的步骤:
  1. 指明一系列的接口来创建一个代理对象
  2. 创建一个调用处理器(InvocationHandler)对象
  3. 将这个代理指定为某个其他对象的代理对象
  4. 在调用处理器的invoke()方法中采取代理,一方面将调用传递给真实对象,另一方面执行各种需要的操作
interface IService {
    void service();
}
class Service implements IService{
    @Override
    public void service() {
        System.out.println("被代理对象执行相关操作");
    }
}
class ServiceInvocationHandler implements InvocationHandler {
    private Object srcObject;
    public ServiceInvocationHandler(Object srcObject) {
        this.srcObject = srcObject;
    }

    @Override
    public Object invoke(Object proxyObj, Method method, Object[] args) throws Throwable {
        System.out.println("开始执行"+method.getName()+"方法");
        //执行原对象的相关操作,容易忘记
        Object returnObj = method.invoke(srcObject,args);
        System.out.println(method.getName()+"方法执行完毕");
        return returnObj;
    }
}
public class ProxyTest {
    public static void main(String[] args) {
        IService service = new Service();
        Class<? extends IService> clazz = service.getClass();
        IService proxyService = (IService) Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(), new ServiceInvocationHandler(service));
        proxyService.service();
    }
}
  • CGlib动态代理:
    利用ASM(开源的Java字节码编辑库,操作字节码)开源包,将代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
interface IService {
    void service();
}
class Service implements IService{
    @Override
    public void service() {
        System.out.println("被代理对象执行相关操作");
    }
}
/**
 * CGlib动态代理类
 */
 public class CGLibProxy implements MethodInterceptor {    
    
    // CGlib需要代理的目标对象
    private Object targetObject;
    
    public Object createProxyObject(Object obj) {
        this.targetObject = obj;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(obj.getClass());
        enhancer.setCallback(this);
        Object proxyObj = enhancer.create();
        return proxyObj;
    }
    
    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        Object obj = null;
        // 过滤方法
        if ("addUser".equals(method.getName())) {
            // 检查权限
            checkPopedom();
        }
        obj = method.invoke(targetObject, args);
        return obj;
    }    
    
    private void checkPopedom() {
        System.out.println("检查权限:checkPopedom()!");
    }
}

public class ProxyTest {
    public static void main(String[] args) {
        IService service = new Service();
        IService proxyService = (IService) new CGLibProxy().createProxyObject(new Service());
        proxyService.service();
    }
}

【五】策略模式

将算法的责任和本身进行解耦,使得:

  • 算法可独立于使用外部而变化
  • 客户端方便根据外部条件选择不同策略来解决不同问题
    我们举一个销售策略的例子,在不同的时节,需要使用不同的销售方式,因此定义如下:
// 定义接口方法
public abstract class Strategy {  
    public abstract void show();
}
//为春节准备的促销活动A
class StrategyA extends Strategy{
	@Override
	public void show() {
		System.out.println("为春节准备的促销活动A");
	}
}
 
//为中秋节准备的促销活动B
class StrategyB extends Strategy{
	@Override
	public void show() {
		System.out.println("为中秋节准备的促销活动B");
	}
}
 
//为圣诞节准备的促销活动C
class StrategyC extends Strategy{
    @Override
    public void show() {
        System.out.println("为圣诞节准备的促销活动C");
    }
}
public class SalesMan {
	//持有抽象策略角色的引用
    private Strategy strategy;
    //生成销售员实例时告诉销售员什么节日(构造方法)
    //使得让销售员根据传入的参数(节日)选择促销活动(这里使用一个简单的工厂模式)
    public  SalesMan(String festival) {
        switch ( festival) {
            //春节就使用春节促销活动
            case "A":
                strategy = new StrategyA();
                break;
            //中秋节就使用中秋节促销活动
            case "B":
                strategy = new StrategyB();
                break;
            //圣诞节就使用圣诞节促销活动
            case "C":
                strategy = new StrategyC();
                break;
        }
    }
    //向客户展示促销活动
    public void SalesManShow(){
        strategy.show();
    }
}

【六】观察者模式

观察者模式使用三个类 Subject、Observer 和 Client。
Subject 对象带有绑定观察者到 Client 对象和从 Client 对象解绑观察者的方法。我们创建 Subject 类、Observer 抽象类和扩展了抽象类 Observer 的实体类。

1、创建 Subject 类。
在这里插入图片描述
2、创建 Observer 类。
在这里插入图片描述
3、创建实体观察者类
在这里插入图片描述
4、使用 Subject 和实体观察者对象。
在这里插入图片描述

【七】链接

https://blog.csdn.net/XSL1990/article/details/16359289

https://blog.csdn.net/qq_38024548/article/details/80480831
https://blog.csdn.net/qq_25827845/article/details/52932234
https://blog.csdn.net/ljh0302/article/details/81562415
https://wenku.baidu.com/view/13354aabf021dd36a32d7375a417866fb84ac077.html
https://wenku.baidu.com/view/e7b1620b51e79b896902265f.html
设计模式常见的面试题
设计模式面试题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值