常用设计模式(单例,代理,工厂,观察者)
单例:线程池、任务管理器。
1.饿汉模式:类加载时就创建好单例对象,调用静态方法返回单例对象,不需要考虑多线程问题。
class Singleton{
private static singleInstance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return singleInstance;
}
}
2.懒汉模式:在调用方法时再创建单例对象
class Singleton{
private static volatile Singleton singleInstance = null;
private Singleton(){}
public static synchronized getInstance(){
if(singleInstance==null){
singleInstance = new Singleton();
}
return singleInstance;
}
}
简单工厂模式:
public class LenovoComputer extends Computer{
@Override
public void start() {
System.out.println("联想电脑启动");
}
public class AsusComputer extends Computer {
@Override
public void start() {
System.out.println("华硕电脑启动");
}
}
public class HpComputer extends Computer{
@Override
public void start() {
System.out.println("惠普电脑启动");
}
}
public class ComputerFactory {
public static Computer createComputer(String type){
Computer mComputer=null;
switch (type) {
case "lenovo":
mComputer=new LenovoComputer();
break;
case "hp":
mComputer=new HpComputer();
break;
case "asus":
mComputer=new AsusComputer();
break;
}
return mComputer;
}
}
public class CreatComputer { public static void main(String[]args){ ComputerFactory.createComputer("hp").start(); } }
将我们要生产的产品共同继承或者实现一个特定的接口,然后调用工厂的静态方法并且传递参数,就会根据参数调用接口的不同的实例对象。
策略模式:
将完成一件事情的不同方法封装为类,然后根据实际情况选择不同的处理方法。http://c.biancheng.net/view/1378.html详情见这篇文章。
构成:
抽象策略:具体策略的公共接口,策略的公共代码写在这里,上下文环境类持有该接口引用,使用该引用调用不同的策略。
具体策略:完成一件事情的方法,继承抽象策略接口,实现策略方法。
上下文环境类:持有策略引用,客户端调用该类对象。
简单工厂和策略很像,不同在于,
通过向工厂传递参数,工厂返回对象。
策略是,传递对象,然后就可以产生相应的行为。
策略模式的扩展:
在一个使用策略模式的系统中,当存在的策略很多时,客户端管理所有策略算法将变得很复杂,如果在环境类中使用策略工厂模式来管理这些策略类将大大减少客户端的工作复杂度。
原理是,在上下文对象中持有一个map容器,key是不同策略的字符串,value是单例对象。根据客户端传进来的字符串,选择不同的实例对象。
观察者模式
http://c.biancheng.net/view/1390.html又叫订阅/发布模式
构成:
抽象观察者(接口)
具体观察者
抽象目标(注意是抽象类!)(相当于中介,真正的事件发生时,通知中介,中介再调用notify方法通知各个观察者)
具体目标
抽象目标之所以是抽象类,是因为里边要有具体的方法。
![]()
该模式最重要的也是抽象目标里的方法,图中这几个方法
都是具体实现的,而在具体目标中,
代理模式:
思想:静态代理,可以代理某个接口下的所以具体实现类的对象方法,当时还是不够解耦合,需要站在更高的角度,对所有接口都能代理,而不是某个接口下的所有具体实现类,所以利用java反射中的class
类,站在这个高度上,就可以对所有接口都代理。这就是动态代理。
优点:可以在不修改方法的基础上对方法进行增强。
静态代理:代理类和具体类一起实现某个接口,所以代理类和具体类有同名方法,在代理类的同名方法中进行增强后,调用具体类中的方法(代理类中持有一个接口的引用)。
*****动态代理(JDK)*******
既然有了静态代理为什么还要创造动态代理呢,
原因是:1.静态代理类实现了某个具体的接口,所以,只能代理实现了该接口的对象,这样,当我们要代理其他许许多多的接口的时候就要创建许许多多个代理类来实现这些接口,这非常不好冗余复杂。
2.并且我们要对某个具体对象的就一个方法都进行增强时,(即使只是在执行前打印一句话)也要在代理类内部实现该接口下的所有方法。
动态代理:利用jdk中的Proxy类和InvocationHandler来实现。
1public class Test{
2 public static void main(String[] args) {
3 Singer target = new Singer();
4 ISinger proxy = (ISinger) Proxy.newProxyInstance(
5 target.getClass().getClassLoader(),
6 target.getClass().getInterfaces(),
7 new InvocationHandler() {
8 @Override
9 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
10 System.out.println("向观众问好");
11 //执行目标对象方法
12 Object returnValue = method.invoke(target, args);
13 System.out.println("谢谢大家");
14 return returnValue;
15 }
16 });
17 proxy.sing();
18 }
19 }
首先Proxy类调用newProxyInstance会创建一个代理类对象,该对象拥有被代理类的所有方法实现,并且所有方法调用时都是增强版本。
原理:先看参数
newProxyInstance的第一个参数是被代理类的类加载器
第二个是,被代理类继承的所有接口
那么有了这两个参数,我们就可以创建一个被代理类的对象了,这个对象只比被代理类的对象多一个引用,就是
InvocationHandler的引用,调用代理对象的方法时,方法体内部就是调用这个接口的invoke方法,然后实现了增强。具体增强原理看该接口的invoke方法,
InvocationHandler的增强原理:
看参数,第一个是代理的this指针,一般是隐式参数
第二个:是methid对象
第三个是方法需要的参数。
然后用匿名内部类来实现。
。


浙公网安备 33010602011771号