目录
设计模式在我们设计编程中,逐渐总结出的一些解决问题的套路
1单例模式
单例:只有一个实例(实例化对象),在整个系统中,这个类只被实例化一次
懒汉式:在第一次调用getInstance()来new对象,以后再有人调用getInstance()直接返回直接new好的对象
饿汉式:在类加载之后,还没有加载,先new好一个对象,之后无论谁调用getInstance()方法,就直接返回之前new好的对象;
例如:实例化对象的创建要消耗大量的时间和资源
饿汉式
/**
* 实现饿汉式的单例
* //构造中执行1000行代码,要占用很大的资源,耗时10s
* 每一次new Single对象都需要10秒,运行1000行代码
* 这情况,适合单例模式,只new一次对象,以后一直用这个对象
* 使用单例模式解决的问题,一般new对象太费劲,频繁new对象没有必要
* 实现饿汉式的单例
*/
public class Single {
private Single() {
}
//私有的single类型的类变量
private static Single single = new Single();
//共有的
public static Single getInstance() {
return single;
}
}
懒汉式(存在线程安全)
/**
* 懒汉式 最开始是null,直到有第一个调用我,才new一个对象
* 之后所有调用我都用这个对象
*/
public class Sing1 {
//先私有化构造方法,在外面不能直接new对象
private Sing1(){
}
private static Sing1 s1=null;
public static Sing1 getInstance(){
if (s1==null){
s1=new Sing1();
}
return s1;
}
}
2模板设计模式
抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。
解决的问题:
Ø
当功能内部一部分实现是确定,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。
/**
* 模板设计模式
*/
public abstract class Template {
public final void getTime() {//给子类使用,但是不允许子类重写
long start = System.currentTimeMillis();
code();
long end = System.currentTimeMillis();
System.out.println("执行时间是:" + (end - start));
}
public abstract void code();
}
class SubTemplate extends Template {
public void code() {
for (int i = 0; i < 10000; i++) {
System.out.println(i);
}
}
}
测试
Template t=new Template();
t.getTime();
打印-----------
3工厂设计模式
FactoryMethod模式是设计模式中应用最为广泛的模式,在面向对象的编程中,对象的创建工作非常简单,对象的创建时机却很重要。FactoryMethod解决的就是这个问题,它通过面向对象的手法,将所要创建的具体对象的创建工作延迟到了子类,从而提供了一种扩展的策略,较好的解决了这种紧耦合的关系。
通过工厂把new对象隔离,通过产品的接口可接受不同实际产品的实现类,实现类名的改变不影响其他合作开发人员的编程
A人员
/**
* 宝马车的产品接口
*
*/
public interface BWM {
//产品的信息介绍
//车的发动方式
void showInfo();
}
class BWM3i implements BWM {
public void showInfo() {
System.out.println("这个是宝马3系");
}
}
class BWM5 implements BWM {
public void showInfo() {
System.out.println("这个是宝马5系");
}
}
/**
* 汽车生产工厂接口
* @author haoby
*/
public interface BWMFactory {
BWM productBWM();
}
class BWM3Facrory implements BWMFactory{
public BWM productBWM() {
System.out.println("生产宝马3工厂");
System.out.println("改造宝马3系工厂");
return new BWM3i();
}
}
class BWM5Facrory implements BWMFactory{
public BWM productBWM() {
System.out.println("生产宝马5工厂");
return new BWM5();
}
}
}
B人员
/**
* @author haoby
*/
public class Test {
public static void main(String[] args) {
BWM bwm3 = new BWM3Facrory().productBWM();
bwm3.showInfo();
BWM bwm5 = new BWM5Facrory().productBWM();
bwm5.showInfo();
}
}
测试结果
生产宝马3工厂
改造宝马3系工厂
这个是宝马3系
生产宝马5工厂
这个是宝马5系
4 动态代理
public interface ITestDemo {
void test1();
void test2();
}
public class TestDemoImpl implements ITestDemo {
@Override
public void test1() {
System.out.println("执行方法一");
}
@Override
public void test2() {
System.out.println("执行方法二");
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 动态代理类
*/
public class ProxyDemo implements InvocationHandler {
Object obj;//被代理对象
public ProxyDemo(Object obj){
this.obj=obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method.getName()+"方法开始执行");
Object result = method.invoke(this.obj, args);//执行的是指定代理对象的指定的方法
return result;
}
}
public class Test {
public static void main(String[] args) {
ITestDemo test=new TestDemoImpl();
/**
* 注意:如果一个对象想要通过Proxy.newProxyInstance方法被代理,
* 那么这个对象的类一定要有相应的接口
* 就像本类中的ITestDemo接口和实现类TestDemoImpl
*/
test.test1();
test.test2();
System.out.println("====================");
/**
* 需求:
* 在执行test1和test2方法时需要加入一些东西
* 在执行方法前打印test1或test2开始执行
* 在执行方法后打印test1或test2执行完毕
* 打印的方法名要和当时调用方法保存一致
*/
InvocationHandler handler=new ProxyDemo(test);
/**
* Proxy.newProxyInstance(ClassLoader, interfaces, h)
* 参数1是代理对象的类加载器
* 参数2是被代理的对象的接口
* 参数3是代理对象
*
* 返回的值就成功被代理后对象,返回的是Object类型,需要根据当时的情况去转换类型
*/
ITestDemo o = (ITestDemo)Proxy.newProxyInstance(handler.getClass().getClassLoader(), test.getClass().getInterfaces(), handler);
o.test1();
System.out.println("-------------");
o.test2();
}
}
执行方法一
执行方法二
====================
test1方法开始执行1025
执行方法一
-------------
test2方法开始执行1025
执行方法二