java设计模式之代理模式(动态代理)

  今天给大家分享的是java设计模式之代理模式中的动态代理模式。如有不足,敬请指正。


  我们上次说到静态代理使用一个代理类来管理被代理类对象(源对象)的统一处理,代理类必须要继承或者实现一个基类或者接口!!(很笨重)。每个接口都要实现一个新的代理,每个方法的逻辑处理,还是要重复编写。

  那么动态代理:就是可以自由的不指定的使用任何接口来实现代理。所谓的动态就不需要指定代理类的固定接口。


  我们本次用模拟通过代理购买火车票来解释动态代理。

图示

一、创建实体类Ticket

package com.xkt.pojo;

import java.util.Date;

/**
 * @author lzx
 *
 */
public class Ticket { private int id; private String start; // 发出的 private String destination; // 目的地 private Date startTime; // 出发时间 private float price; // 价格 public Ticket() { super(); // TODO Auto-generated constructor stub } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getStart() { return start; } public void setStart(String start) { this.start = start; } public String getDestination() { return destination; } public void setDestination(String destination) { this.destination = destination; } public Date getStartTime() { return startTime; } public void setStartTime(Date startTime) { this.startTime = startTime; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } @Override public String toString() { return "Ticket [id=" + id + ", start=" + start + ", destination=" + destination + ", startTime=" + startTime + ", price=" + price + "]"; } } 

二、创建一个公共接口TicketDao

package com.xkt.dao;

import java.util.Date;

import com.xkt.pojo.Ticket;

/**
 * @author lzx * */ public interface TicketDao { /** * 售票的基础dao * * @param start 出发地 * @param destination 目的地 * @param date 出发日期 * @param type 1:火车票 2:机票 * @return */ Ticket getTicket(String start,String destination,Date date); } 

三、创建其实现

3.1 TrainTicketDaoImpl

package com.xkt.dao.impl;

import java.util.Date;

import com.xkt.dao.TicketDao;
import com.xkt.pojo.Ticket;

/** * @author lzx * */ public class TrainTicketDaoImpl implements TicketDao { @Override public Ticket getTicket(String start, String destination, Date date) { Ticket t = new Ticket(); // 模拟查询数据库,获取票信息 t.setId(1); t.setDestination(destination); t.setStart(start); t.setStartTime(date); t.setPrice(300.0f); if ("武汉".equals(start) && "广州".equals(destination)) { t.setPrice(463.0f); } else if ("北京".equals(start) && "广州".equals(destination)) { t.setPrice(885.0f); } else { t.setPrice(500.0f); } System.out.println("---您已购买从 " + start + " 到 " + destination + " 的火车票,请注意发车时间---"); return t; } } 

3.2 FlightTicketDaoImpl

package com.xkt.dao.impl;

import java.util.Date;

import com.xkt.dao.TicketDao;
import com.xkt.pojo.Ticket;

/** * @author lzx * */ public class FlightTicketDaoImpl implements TicketDao { @Override public Ticket getTicket(String start, String destination, Date date) { Ticket t = new Ticket(); // 模拟查询数据库,获取票信息 t.setId(1); t.setDestination(destination); t.setStart(start); t.setStartTime(date); t.setPrice(300.0f); if ("武汉".equals(start) && "广州".equals(destination)) { t.setPrice(1000.0f); } else if ("北京".equals(start) && "广州".equals(destination)) { t.setPrice(2000.0f); } else { t.setPrice(500.0f); } System.out.println("---您已购买从 " + start + " 到 " + destination + " 的机票,请注意起飞时间---"); return t; } } 

四、创建代理类YellowCrow

package com.xkt.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Date; import com.xkt.pojo.Ticket; /** * @author lzx * */ public class YellowCrow implements InvocationHandler { // 1、指定代理源(被代理对象) private Object source; // 2、创建代理对象,其实就是黄牛本身 public Object createProxy(Object source) { this.source = source; // 1、拿到接口 Class<?>[] interfaces = source.getClass().getInterfaces(); // 2、拿到classloader ClassLoader classLoader = source.getClass().getClassLoader(); // 3、创建代理对象 Object proxyInstance = Proxy.newProxyInstance(classLoader, interfaces, this); return proxyInstance; } // args:执行方法过程中的参数 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String start = (String) args[0]; String destination = (String) args[1]; Date date = (Date) args[2]; // 通过代理,执行真正购票 Ticket invoke = (Ticket) method.invoke(source, args); System.out.println("--黄牛加价100--"); invoke.setPrice(invoke.getPrice() + 100); return invoke; } } 

五、测试

package com.xkt.test;

import java.util.Date;

import com.xkt.dao.TicketDao;
import com.xkt.dao.impl.FlightTicketDaoImpl;
import com.xkt.dao.impl.TrainTicketDaoImpl; import com.xkt.pojo.Ticket; import com.xkt.proxy.YellowCrow; /** * @author lzx * */ public class TicketClient { public static void main(String[] args) { // 不通过代理购票,自己在12306上抢 TicketDao tDao = new TrainTicketDaoImpl(); /* * Ticket ticket = tDao.getTicket("武汉", "广州", new Date()); * System.out.println(ticket); */ // 自己购票失败,只能找黄牛 YellowCrow crow = new YellowCrow(); TicketDao tDoProxy = (TicketDao) crow.createProxy(tDao); Ticket ticket2 = tDoProxy.getTicket("武汉", "广州", new Date()); System.out.println(ticket2); testFlight(); } private static void testFlight() { // 1、不通过黄牛,直接去官网购买 TicketDao tDao = new FlightTicketDaoImpl(); /* * Ticket t1 = tDao.getTicket("武汉", "广州", new Date()); System.out.println(t1); */ // 通过黄牛购买 YellowCrow crow = new YellowCrow(); TicketDao createProxy = (TicketDao) crow.createProxy(tDao); Ticket t2 = createProxy.getTicket("武汉", "广州", new Date()); System.out.println(t2);

  from openpyxl import load_workbook
  
  from openpyxl.styles import Font
  
  from openpyxl.styles.colors import BLACK
  
  from collections import namedtuple
  
  class ParseExcel(object):
  
  """解析excel文件"""
  
  def __init__(self, filename, sheet_name=None):
  
  try:
  
  self.filename = filename
  
  self.sheet_name = sheet_name
  
  self.wb = load_workbook(self.filename)
  
  if self.sheet_name is None:
  
  self.work_sheet = self.wb.active
  
  else:
  
  self.work_sheet = self.wb[self.sheet_name]
  
  except FileNotFoundError as e:
  
  raise e
  
  def get_max_row_num(self):
  
  """获取最大行号"""
  
  max_row_num = self.work_sheet.max_row
  
  return max_row_num
  
  def get_max_column_num(self):
  
  """获取最大列号"""
  
  max_column = self.work_sheet.max_column
  
  return max_column
  
  def get_cell_value(self, coordinate=None, row=None, column=None):
  
  """获取指定单元格的数据"""
  
  if coordinate is not None:
  
  try:
  
  return self.work_sheet[coordinate].value
  
  except Exception as e:
  
  raise e
  
  elif coordinate is None and row is not None and column is not None:
  
  if isinstance(row, int) and isinstance(column, int):
  
  return self.work_sheet.cell(row=row, column=column).value
  
  else:
  
  raise TypeError('row and column www.yunyouuyL.com must be type int')
  
  else:
  
  raise Exception("Insufficient Coordinate of cell!")
  
  def get_row_value(self, row):
  
  """获取某一行的数据"""
  
  column_num = self.get_max_column_num()
  
  row_value = []
  
  if isinstance(row, int):
  
  for column in range(1, column_num + 1):
  
  values_row = self.work_sheet.cell(row, column).value
  
  row_value.append(values_row)
  
  return row_value
  
  else:
  
  raise TypeError('row must be type int')
  
  def get_column_value(self,www.yunyouguoj.com column):
  
  """获取某一列数据"""
  
  row_num = self.get_max_column_num()
  
  column_value = []
  
  if isinstance(column, int):
  
  for row in range(1, row_num + 1):
  
  values_column = self.work_sheet.cell(row, column).value
  
  column_value.append(values_column)
  
  return column_value
  
  else:
  
  raise TypeError('column must be type int')
  
  def get_all_value_1(self):
  
  """获取指定表单的所有数据(除去表头)"""
  
  max_row_num = self.get_max_row_num()
  
  max_column = self.get_max_column_num()
  
  values = []
  
  for row in range(2, max_row_www.shengryll.com/ num + 1):
  
  value_list = []
  
  for column in range(1, max_column + 1):
  
  value = self.work_sheet.cell(row, column).value
  
  value_list.append(value)
  
  values.append(value_list)
  
  return values
  
  def get_all_value_2(self):
  
  """获取指定表单的所有数据(除去表头)"""
  
  rows_obj = self.work_sheet.iter_rows(min_row=2, max_row=self.work_sheet.max_row,
  
  values_only=True) # 指定values_only 会直接提取数据不需要再使用cell().value
  
  values = []
  
  for row_tuple in rows_obj:
  
  value_list = []
  
  for value in row_tuple:
  
  value_list.append(value)
  
  values.append(value_list)
  
  return values
  
  def get_excel_title(self):
  
  """获取sheet表头"""
  
  title_key = tuple(www.yunyougp.com self.work_sheet.iter_rows(max_row=1, values_only=True))[0]
  
  return title_key
  
  def get_listdict_all_value(self):
  
  """获取所有数据,返回嵌套字典的列表"""
  
  sheet_title = self.get_excel_title()
  
  all_values = self.get_all_value_2()
  
  value_list = []
  
  for value in all_values:
  
  value_list.append(dict(zip(sheet_www.xinhuiyule1.cn/ title, value)))
  
  return value_list
  
  def get_list_nametuple_all_value(self):
  
  """获取所有数据,返回嵌套命名元组的列表"""
  
  sheet_title = self.get_excel_title()
  
  values = self.get_all_value_2()
  
  excel = namedtuple('excel', sheet_title)
  
  value_list = []
  
  for value in values:
  
  e = excel(*value)
  
  value_list.append(e)
  
  return value_list
  
  def write_cell(self, row, column, value=None, bold=True, color=BLACK):

测试结果
  1. 可以看出可以不用创建多个代理对象
  2. 动态代理模式的好处,就是一个代理类可以代理多个种类型(接口不同)的对象
  3. 基于动态代理模式可以处理多个类型的类的对象,所以必须要使用到 JDK 的 Proxy 和InvocationHandler 来说实现
  4. 使用 JDK 自带的 API 实现动态代理,必须要使用接口来原始类的接口接收对象

转载于:https://www.cnblogs.com/qwangxiao/p/10860667.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值