1.设计模式:通俗的来说就是设计的一些套路。
2.设计模式的要素:
- 名称
- 解决的问题
- 解决的方案
3.面向对象的设计原则:
整体原则是高内聚,低耦合
- 单一职责原则:一个类最好只做一件事
- 开闭原则:对修改关闭,对扩展开放
- 依赖倒转原则:依赖抽象而不依赖具体类
- 接口隔离原则:每个接口的职责单一
- 里氏代换原则:子类可以替换父类
4.设计模式一共有23种,分为三类:
- 创建型:工厂,单例,原型…
- 结构型:装饰…
- 行为型
代理模式
现实中代理的式例:找保姆-》中介;租房-》中介;
代理模式的角色:
- 抽象角色(抽象的类或接口)
- 真实角色
- 代理角色
租房实例(静态代理):
- 抽象角色(对房主和中介的抽取)
- 真实角色(房主)
- 代理角色(中介)
第一步:创建Res接口
public interface Res {
public void buy(int money);
}
第二步:创建接口的两个实现类Houser,Intermediary
public class Houser implements Res {
@Override
public void buy(int money) {
// TODO Auto-generated method stub
if (money > 2000) {
System.out.println("租房成功");
}else {
System.out.println("租房失败");
}
}
}
public class Intermediary implements Res {
Houser obj;
public Intermediary(Houser obj) {
super();
this.obj = obj;
}
public Intermediary() {
super();
}
@Override
public void buy(int money) {
System.out.println("带你看房");
if (money > 2500) {
obj.buy(money-money/5);
}else {
System.out.println("服务终止");
}
}
}
第三步:测试
public class Test {
public static void main(String[] args) {
Intermediary intermediary = new Intermediary(new Houser());
intermediary.buy(12000);
}
静态代理的缺点:如果有多个真实角色我们需要为每一个真实角色,定义一个与之关联的代理角色,这样会造成类数据的急剧膨胀。
动态代理
动态代理可以为我们动态的生成代理类和代理对象。
java代理的两种实现方式:
- jdk动态代理:
- CGlib的动态代理
动态代理理解:
类继承invocationHandler{ invoke();}
真实对象:Houser
代理对象:名=Proxy.newProxyInstance(ClassLoader,接口,MyinvocationHandler);
注意:Proxy.newProxyInstance()返回的类型是接口;
JDK动态开发步骤:
- 创建抽象角色(接口)
- 创建真实角色(实现接口)
- 创建类实现invocationHandler接口,重写invoke方法
- 测试:实例化代理的真实对象,实例化实现invocationHandler接口的类,创建代理对象,最后调用方法测试
JDK动态开发代码区:
public interface Res {
public void buy(int money);
}
public class Houser implements Res {
@Override
public void buy(int money) {
// TODO Auto-generated method stub
if (money > 2000) {
System.out.println("租房成功");
}else {
System.out.println("租房失败");
}
}
}
public class MyIncocationHandler implements InvocationHandler {
Object obj;
public MyIncocationHandler(Object obj) {
super();
this.obj = obj;
}
public MyIncocationHandler() {
super();
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Long startLong = System.currentTimeMillis();
System.out.println(method.getName()+"的方法被调用");
Object object = method.invoke(obj, args);
System.out.println(method.getName()+"的方法调用完毕,总耗时"+(System.currentTimeMillis()-startLong));
return object;
}
}
public class Test {
public static void main(String[] args) {
// Intermediary intermediary = new Intermediary(new Houser());
// intermediary.buy(12000);
//要代理的真实对象
Res houser = new Houser();
// 要代理哪个真实对象,就将该对象传进去,最后是通过该真实对象来调用其方法的
MyIncocationHandler m = new MyIncocationHandler(houser);
Res h = (Res) Proxy.newProxyInstance(Res.class.getClassLoader(),houser.getClass().getInterfaces(), m);
h.buy(100000);
}
}
报错区:
com.sun.proxy.$Proxy0 cannot be cast to com.oracle.proxy.Houser
写代码的时候碰到了这样一个错误,这是由于用类来接收Proxy.newProxyInstance(),然而Proxy.newProxyInstance()的返回值类型是接口
错误代码:
Houser h = (Houser) Proxy.newProxyInstance(Res.class.getClassLoader(),houser.getClass().getInterfaces(), m);
应改为
Res h = (Res) Proxy.newProxyInstance(Res.class.getClassLoader(),houser.getClass().getInterfaces(), m);