Java中的设计模式(这里介绍三种)

一、什么是设计模式

设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。
设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结.

二、设计模式的作用

使用设计模块是为了重用代码、让代码更容易被他人理解,保证代码可靠性

三、常见的设计模式

 常见的设计模型有23中
3.1单例模式
单类模式----保证一个类仅有一个实例
当类频繁地创建与销毁的时候,我们使用单例模式,这样可以减少了内存的开销,避免对资源的多重占用
单例模式条件:
1.构造方法私有
2.提供一个静态方法【公共】返回创建好的当前类对象
两种表示方式:
1.懒汉式
例如:

package com.wangxing.test1;
/*
 * 懒汉式
 */
public class lanhan {
	//创建构造方法
	public lanhan(){}
	//先创建好lanhan对象
	private static lanhan obj=null;
	//创建过得lanhan类对象的方法,避免每次创建出新的对象减少内存的开销
	public static lanhan getlanhanClass(){
		if (obj==null) {
			obj=new lanhan();
		}
		return obj;
	}
}


2.饿汉式
例如:

package com.wangxing.test1;
/*
 * 饿汉式
 */
public class ehan {
	//创建构造方法
	public ehan(){}
	//提前创建好ehan对象
	private static ehan obj=new ehan();
	//创建得到饿汉对象的方法
	public synchronized static ehan getehanClass(){
		return obj;
	}
}

懒汉式与饿汉式的区别
相同点:保证当前类的对象只有一个
书写上:
        1.构造方法私有
         2.提供一个静态方法【公共】返回创建好的当前类对象
不同点:
        书写上:懒汉式中保存当前类的对象变量初始为null,
                    饿汉式中保存当前类的对象变量初始为new好的当前类对象
        运行速度上:懒汉式比饿汉式稍微差一些。
        资源利用率:饿汉式比懒汉式稍微差一些。
3.2工厂模式
工厂模式---有一个专门的Java类充当生产对象的工厂
使用工厂模式的条件:
1.需求量大
2.牵一发,动全身
工厂模式中的角色:
       工厂角色---生产对象
        抽象产品对象-----【抽象/接口】
        具体产品------【抽象类/接口类】
例如:有农场各种水果,有西瓜。苹果,香蕉等
            工厂角色-----农厂
            抽象产品角色-----水果
            西瓜、苹果、香蕉----具体产品
1. 先创建抽象产品的共同功能接口

package com.wangxing.test2;

public interface ShuiGuo {
	void eat();
}

2.创建每个具体的水果的类继承功能

package com.wangxing.test2;

public class PingGuo implements ShuiGuo{

	@Override
	public void eat() {
		System.out.println("我是苹果,需要清洗以后吃!!!");
	}
}
package com.wangxing.test2;

public  class xigua implements shuiguo{

	@Override
	public void eat() {
		System.out.println("我是西瓜,切开吃");
	}
}

3.创建农场的用户选择水果是系统菜单,根据菜单得到某个水果对应的反射对象去创建实例对象
menu.txt
苹果=com.wangxing.test2.pingguo
西瓜=com.wangxing.test2.xigua
4.创建农厂类实现工厂模式

package com.wangxing.test2;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.HashMap;

/**
 * 
 * @author Administrator
 *
 */
public class NongChang {

	public  static  ShuiGuo  createShuiGuo(String name){
		ShuiGuo  sg=null;
		//读取菜单
		HashMap<String,String>  menuMap=readMenu();
		String className=menuMap.get(name);
		try{
		//利用反射机制创建对象
	    Class  classobj=Class.forName(className);
	    sg=(ShuiGuo)classobj.newInstance();
		}catch(Exception e){
			e.printStackTrace();
		}
		return sg;
	}
	/**
	 * 读取菜单	
	 */
	private static HashMap<String,String> readMenu() {
		HashMap<String,String>  menuMap=new HashMap<String,String>();
		try{
		BufferedReader  read=new BufferedReader(new FileReader(new File("menu.txt")));
		String menuitem=null;
		while((menuitem=read.readLine())!=null){
			//苹果=com.wangxing.test2.PingGuo
			String menuarray[]=menuitem.split("=");
			menuMap.put(menuarray[0],menuarray[1]);
		}
		read.close();
		}catch(Exception e){
			
		}
		return menuMap;
	}
}

5.创建测试类

package com.wangxing.test2;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class TestMain {

	public static void main(String[] args) throws Exception{
		BufferedReader  read=new BufferedReader(new InputStreamReader(System.in));
		System.out.println("请输入需要的水果:");
		String  name=read.readLine();
		ShuiGuo   pg=NongChang.createShuiGuo(name);
		pg.eat();
	}

}

 这时我们不需要通过得到用户的需求判断再去每次new水果对象,而是交给工厂自己去创建实例对象得到具体东西。避免了重复代码书写。
3.3代理模式
代理模式----为其他对象提供一种代理以控制对这个对象的访问
买火车票不一定在火车站买,也可以在代售点
代理模式被分为静态代理和动态代理
静态代理有被分为兄弟模式和父子模式
缺点:需要额外提供业务功能实现相似的子类【工作量大】
兄弟模式----同一个接口的两个子类
例如:
1.创建一个火车站和代售点有共同功能的接口

package com.wangxing.test3;

public interface SellPiao {
	void maiPiao();
}

2.让火车站和代售点继承这个接口

package com.wangxing.test3;

public class huoCheZhan implements SellPiao{

	@Override
	public void maiPiao() {
		System.out.println("我是火车票,在火车站买票中");
	}
}
package com.wangxing.test3;

public class daiShouDian implements SellPiao{

	@Override
	public void maiPiao() {
		System.out.println("我是代售点,在买票中");
	}
}

3.测试

package com.wangxing.test3;

public class Main {

	public static void main(String[] args) {
		huoCheZhan hcz=new huoCheZhan();
		hcz.maiPiao();
		daiShouDian dsd=new daiShouDian();
		dsd.maiPiao();
	}
}

 父子模式---继承关系
1.创建一个父类

package com.wangxing.test4;

public class huoCheZhan {
	public void maipiao(){
		System.out.println("我是火车站,正在卖票");
	}
}

2.创建一个子类继承父类重写卖票的方法

package com.wangxing.test4;

public class daiShouDian extends huoCheZhan{
	public void maipiao(){
		System.out.println("我是代售点,正在卖票");
	}
}

3.测试

package com.wangxing.test4;

public class Main {
	public static void main(String[] args) {
		huoCheZhan hc=new huoCheZhan();
		hc.maipiao();
		daiShouDian ds=new daiShouDian();
		ds.maipiao();
	}
}

动态代理---由一个java类来负责创建代理类的对象
    JDK动态代理----通过java.lang.reflect包 Class Proxy类来创建代理类对象
   【只能为实现过某个接口的java类提供代理类对象】
例如:
1..创建接口

package com.wangxing.test5;

public interface SellPiao {
	void maipiao();
}

2.创建继承接口的类

package com.wangxing.test5;

public class huoCheZhan implements SellPiao{

	@Override
	public void maipiao(){
		System.out.println("我是火车站,正在卖票");
	}
}

3.创建动态代理,通过实现接口的类得到反射对象从而得到接口子类继承接口的方法,直接创建新的对象但是使用的还是接口子类的方法

package com.wangxing.test5;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyObject implements InvocationHandler{
	  //定义目标对象
	  private  Object targetObject;
	  
	  public ProxyObject(Object targetObject){
		  this.targetObject=targetObject;
	  }
	  
	  //得到代理对象
	  public Object getProxy() {
		  //java.lang.reflect包 Class Proxy类
		  //ClassLoader loader--类加载器
		  ClassLoader loader=this.getClass().getClassLoader();
		  //Class<?>[] interfaces---接口的反射对象
		  Class[] interfaces=this.targetObject.getClass().getInterfaces();
		  //InvocationHandler h---this
		  return Proxy.newProxyInstance(loader, interfaces, this);
	  }

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		return method.invoke(targetObject, args);
	}

}
package com.wangxing.test5;

public class Main {

	public static void main(String[] args) {
		huoCheZhan  hcz=new huoCheZhan();
		hcz.maipiao();
		ProxyObject  proxyobj=new ProxyObject(hcz);
		//代理类对象
		SellPiao dsd=(SellPiao) proxyobj.getProxy();
		dsd.maipiao();
	}
}


     CGlib代理-------CGlib是一个第三发的开发包,用的时候需要自己事先下载导入到项目中
    【所有的java类提供代理类对象】
例如:
 1.创建需要代理的类

package com.wangxing.test6;

public class huoCheZhan{
	public void maipiao(){
		System.out.println("我是火车站,正在卖票");
	}
}

2.创建获得代理对象

package com.wangxing.test6;

import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class ProxyObject implements MethodInterceptor{
	  //定义目标对象
	  private  Object targetObject;
	  
	  public ProxyObject(Object targetObject){
		  this.targetObject=targetObject;
	  }
	  
	  //得到代理对象
	  public Object getProxy() {
		 Enhancer enhancer=new Enhancer();
		 enhancer.setSuperclass(targetObject.getClass());
		 enhancer.setCallback(this);
		 return enhancer.create();
	  }

		@Override
		public Object intercept(Object proxy, Method arg1, Object[] params, MethodProxy methodProxy) throws Throwable {
			return methodProxy.invokeSuper(proxy, params);
		}
}

3.测试

package com.wangxing.test6;

public class Main {

	public static void main(String[] args) {
		huoCheZhan  hcz=new huoCheZhan();
		ProxyObject  proxyobj=new ProxyObject(hcz);
		//代理类对象
		huoCheZhan daili=(huoCheZhan) proxyobj.getProxy();
		daili.maipiao();
	}
}

比较:
1.静态代理是通过在代码中显式定义一个业务实现类一个代理,在代理类中对同名的业务方法进行包装,用户通过代理类调用被包装过的业务方法;
手动创建一个与目标类相同接口的子类,包装目标类。
2.JDK动态代理是通过接口中的方法名,在动态生成的代理类中调用业务实现类的同名方法;【兄弟模式】
通过jdk提供的反射包中Proxy这个类,动态的创建一个与目标类实现相同接口的子类对象,包装目标。
3.CGlib动态代理是通过继承业务类,生成的动态代理类是业务类的子类,通过重写业务方法进行代理。【父子模式】
通过CGlib提供的Enhancer这个类,动态的创建一个目标类的子类对象,包装目标类。

静态代理    JDK动态代理CGlib动态代理
手动创建代理类动态生成代理类对象    动态生成代理类对象
jdk提供的反射包中Proxy这个类CGlib提供的Enhancer这个类
只能为实现过接口的Java类创建代理对象为任何Java类创建代理对象

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java常用的设计模式有很多,以下是一些常见的设计模式: 1. 单例模式(Singleton Pattern):确保一个类只有一个实例,并提供一个全局访问点。 2. 工厂模式(Factory Pattern):通过工厂类创建对象,而不直接使用new关键字。 3. 抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口。 4. 建造者模式(Builder Pattern):将复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。 5. 原型模式(Prototype Pattern):通过复制现有对象来创建新对象,而不是使用new关键字。 6. 适配器模式(Adapter Pattern):将一个类的接口转换成客户端所期望的另一个接口。 7. 装饰器模式(Decorator Pattern):动态地给一个对象添加额外的职责,同时又不改变其结构。 8. 观察者模式(Observer Pattern):定义对象之间的一对多依赖关系,使得当一个对象改变状态时,所有依赖于它的对象都会被通知并自动更新。 9. 策略模式(Strategy Pattern):定义一系列算法,将每个算法封装起来,并使它们可以互相替换。 10. 模板方法模式(Template Method Pattern):定义一个操作的算法骨架,将一些步骤延迟到子类实现。 11. 迭代器模式(Iterator Pattern):提供一种方法顺序访问一个聚合对象的各个元素,而又不暴露其内部的表示。 12. 备忘录模式(Memento Pattern):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以后可以将对象恢复到原先保存的状态。 这里只列举了一些常见的设计模式Java还有其他设计模式可以用于不同场景和需求。每个设计模式都有自己的特点和适用情况,开发人员在实际项目可以根据具体需求选择合适的设计模式来提高代码的可重用性、可维护性和灵活性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值