java常用的设计模式

1.单例模式

    1)饿汉式(不管有没有先创建对象,是线程安全的但是效率比较低)

public class Model {
	//私有化构造器
	private Model(){}
	//在内部产生实例 static final修饰意味着其不可变
	private static final Model model = new Model();
	//提供静态方法对外调用获取实例
	public static Model getModel(){
		return model;
	}
	
}

    2)懒汉式(先判断再创建,线程不安全的,线程在判断之后,创建对象之前被剥夺资源会产生线程安全问题)

class Man{
	//单例模式 懒汉式(先判断再创建,线程不安全的)
	private Man(){}
	private static Man man;
	public static Man getMan(){
		if(man==null){
			man = new Man();
		}
		return man;
	}
}

    3)最终版本(线程安全,效率高)

class Women{
	//最终版本,在代码块上加锁,确保线程安全
	private Women(){}
	private static Women women;
	public static Women getWomen(){
		if(women==null){
			synchronized (Women.class) {
				if(women==null){
					women = new Women();
				}
			}
		}
		return women;
	}
	
}

2.模板设计模式,解决了重复代码

public abstract class Mould {
	
	public static void main(String[] args) {
		TestOne to = new TestOne();
		to.getTime();
	}
	
	//计算一段功能的执行时间
	public void getTime(){
		long start = System.currentTimeMillis();
		
		//执行的功能,当时这段代码不确定
		code();
		
		long end = System.currentTimeMillis();
		System.out.println(end-start);
	}
	
	public abstract void code();
	
}

//当需要测试某个功能执行的时间
class TestOne extends Mould{
	
	//此处编写需要计算的功能代码,可以看出只需要继承抽象类重写要测试的代码功能即可
	@Override
	public void code() {
		// TODO Auto-generated method stub
		
	}
	
}

3.工厂设计模式

工厂设计模式提供了一种创建对象的方式,目的在于解耦,易扩展

首先我们创建产品类

//定义一个抽象的产品接口
public interface Phone {

	void call();
	
}
//分别实现三种产品
public class Iphone implements Phone{

	@Override
	public void call() {
		System.out.println("生产一个苹果手机");
	}

}
public class Sphone implements Phone{

	@Override
	public void call() {
		System.out.println("生产一个索尼手机");
	}

}
public class Wphone implements Phone{

	@Override
	public void call() {
		System.out.println("生产一个wphone");
	}

}

3.1.简单工厂模式

定义简单工厂类如下:

//简单工厂类
public class PhoneFactory {

	public Phone getPhone(String type){
		if("iphone".equals(type)){
			return new Iphone();
		}else if("sphone".equals(type)){
			return new Sphone();
		}else if("wphone".equals(type)){
			return new Wphone();
		}
		return null;
	}
	
}
//测试类
public class Factory {
	public static void main(String[] args) {
		PhoneFactory factory = new PhoneFactory();
		Phone phone = factory.getPhone("iphone");
		phone.call();
	}
}
//执行结果
生产一个苹果手机

3.2.工厂模式方法

针对每一种产品提供一个工厂,相对于简单工厂来说,再增加产品只需要增加工厂类就可以,不用管工厂类的逻辑代码:

//定义公共工厂接口
public interface ShapeFactory {

	public Phone getPhone();
	
}

public class Ishapefactory implements ShapeFactory {

	@Override
	public Phone getPhone() {
		// TODO Auto-generated method stub
		return new Iphone();
	}

}

public class Sshapefactory implements ShapeFactory{

	@Override
	public Phone getPhone() {
		// TODO Auto-generated method stub
		return new Sphone();
	}

}

public class Wshapefactory implements ShapeFactory {

	@Override
	public Phone getPhone() {
		// TODO Auto-generated method stub
		return new Wphone();
	}

}

//测试类
public class Test {

	public static void main(String[] args) {
		//通过子类工厂去生产特定的对象
		Ishapefactory ifa = new Ishapefactory();
		ifa.getPhone().call();
	}
	
}

//运行结果
生产一个苹果手机

3.3.抽象工厂方法,

抽象工厂方法类似上述工厂模式方法,只是将工厂也抽象起来,运用多态的方式去创建想要的目标对象。

4.代理设计模式

代理模式提供了对目标对象的其他访问形式

代理模式中有两个对象,一个目标对象一个代理对象,代理对象是目标对象的扩展,并且可以调用目标对象

4.1.静态代理

静态代理需要定义接口或者父类,目标对象和代理对象需要实现相同的接口或者继承相同的父类

代码如下:

//接口定义
public interface UserDao {

	void save();
	
}
//目标对象实现接口
public class UserDaoImpl implements UserDao {

	@Override
	public void save() {
		System.out.println("执行保存");
	}

}
//代理对象实现接口
public class ProxyUserDaoImpl implements UserDao {

	// 要代理的目标对象
	private UserDaoImpl target;

	public ProxyUserDaoImpl(UserDaoImpl target) {
		super();
		this.target = target;
	}

	@Override
	public void save() {
		System.out.println("方法执行前");
		target.save();
		System.out.println("方法执行后");
	}

}
//测试类
public class Test {

	public static void main(String[] args) {
		//创建目标对象
		UserDaoImpl userDaoImpl = new UserDaoImpl();
		//和代理对象产生关系
		ProxyUserDaoImpl proxyUserDaoImpl = new ProxyUserDaoImpl(userDaoImpl);
		//代理调用方法
		proxyUserDaoImpl.save();
	}
	
}
//运行结果
方法执行前
执行保存
方法执行后

4.2.JDK动态代理(接口代理)

动态在内存中构建代理对象,而且动态代理需要目标对象实现一个接口才可以代理,代码如下:

//接口定义
public interface InterfaceDao {

	boolean save();
	
}
//目标对象实现接口
public class InterfaceDaoImpl implements InterfaceDao {

	@Override
	public boolean save() {
		User u = new User();
		u.setName("xd");
		System.out.println("保存用户:"+u.getName());
		return true;
	}

}
//代理工厂类
public class ProxyFactory {

	//维护目标对象
	private Object target;
	public ProxyFactory(Object target){
		this.target = target;
	}
	
	//给目标对象生成代理对象
	public Object getProxyInstance(){
		//指定当前目标对象使用类加载器
		//目标对象实现的接口类型,使用泛型方式确认类型
		//事件处理
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
			
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				System.out.println("开始事物");
				
				Object result = method.invoke(target, args);
				
				System.out.println("结束事物");
				return result;
			}
		});
		
	}
}
//测试类
public class DynamicTest {

	public static void main(String[] args) {
		
		//创建目标对象
		InterfaceDaoImpl interfaceDaoImpl = new InterfaceDaoImpl();
		System.out.println("目标对象类型"+interfaceDaoImpl.getClass());
		//给目标对象创建代理对象 然后产生关联
		InterfaceDao proxyInstance = (InterfaceDao)new ProxyFactory(interfaceDaoImpl).getProxyInstance();
		System.out.println("代理对象类型"+proxyInstance.getClass());
		proxyInstance.save();
		
	}
	
}
//运行结果
目标对象类型class xd.designmodel.proxydemo.dynamicproxy.InterfaceDaoImpl
代理对象类型class com.sun.proxy.$Proxy0
开始事物
保存用户:xd
结束事物

4.3.cglib动态代理

cglib不像jdk代理一样只能代理接口,它可以代理所有的类型。在内存中构建一个子类对象来是相对目标对象功能的扩展,代码如下:

//目标对象类
public class UserDao {

	public void save(){
		System.out.println("保存成功");
	}
	
}
//代理工厂类(原理是通过拦截器)
public class ProxyFactory implements MethodInterceptor {

	// 同样的给出目标对象
	private Object obj;
	//通过构造器和代理可以产生管理
	public ProxyFactory(Object obj) {
		this.obj = obj;
	}

	// 给目标对象创建代理对象
	public Object getNewInstance() {
		// 工具类
		Enhancer e = new Enhancer();
		// 设置父类
		e.setSuperclass(obj.getClass());
		// 设置回掉函数
		e.setCallback(this);
		// 创建子类(代理对象)
		return e.create();
	}

	@Override
	public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
		System.out.println("开始执行");
		Object invoke = arg1.invoke(obj, arg2);
		System.out.println("执行完成");
		return invoke;
	}

}
//测试类
public class CglibTest {

	public static void main(String[] args) {
		UserDao userDao = new UserDao();
		UserDao proxy = (UserDao)new ProxyFactory(userDao).getNewInstance();
		proxy.save();
	}
	
}
//执行结果
开始执行
保存成功
执行完成

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dong__xue

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值