黑马程序员_ 三种设计模式:单例、模板、装饰

               ------- android培训java培训、期待与您交流! ----------                                 


一、单例设计模式:懒汉式和饿汉式

1.      目的:解决一个类在内存中只存在一个对象,保证对象的唯一性

(1)将构造函数私有化

(2)在类中创建一个本类对象

(3)提供一个方法可以获取到该对象

2.饿汉式:先初始化对象

class Single{

    private static final Single s=new Single();

    private Single();

    public static Single getInstance(){

       returns;

    }

}

2.    懒汉式:对象是方法被调用时才初始化,也叫做对象的延时加载

class Single{

    private static Single s=null;

    private Single();

    public static Single getInstance(){

       if(s==null)

           s=new Single();

       returns;

    }

}

3.懒汉式用于对象的延时加载,在多线程访问时会有安全问题(开发一般用恶汉式,安全)

class Single{

    private static Single s=null;

    private Single();

    public static Single getInstance(){

       if(s==null)

           -->A  

           -->B

//A、B中都用到了Single对象s,线程A执行到这,停止,执行B,B进来,线程B停止,线程A执行,创建了一个Single对象,线程B醒了,向下执行又创建了一个Single对象。

           s=new Single();

       returns;

    }

}

解决方法1,加同步synchronized,效率低

最优解决方法2,加同步代码块,稍微提升一点效率,使用的锁是该类所属的的字节码文件对象

class Single{

    private static Single s=null;

    private Single();

    public static Single getInstance(){

       if(s==null){

           synchronized(Single.class){

              if(s==null)

              s=new Single();

           }

       }

       returns;

    }

}

二、模板方法设计模式:

在定义功能时,功能的一部分是确定的,但是有一部分是不确定的,而确定的部分在使用不确定的部分,那么这时就将不确定的部分暴露出去,由该类的子类去实现

package code;

abstract class GetTime{

    public final void getTime(){

       //获取系统的当前时间作为开始时间

       long start=System.currentTimeMillis();

       //不确定的功能代码块

       runcode();

       //获取系统的当前时间作为开始时间

       long end=System.currentTimeMillis();

       //输出代码块的执行时间,并打印

       System.out.println("代码执行时间(毫秒):"+(end-start));

    }

    //定义一个抽象的runcode()方法

    public abstract void runcode();

}

class SubTimeextends GetTime{

    //实现父类的runcode()方法

    public void runcode(){

       for(int x=0;x<10;x++){

           System.out.print(x+" ");

       }

    }

}

public class Test{

    public static void main(String[] args) {

       SubTime s=new SubTime();

       s.getTime();

    }

}

如上代码,runcode()中封装的不确定的功能代码块,它由确定功能的getTime()方法所使用,就将runcode()定义成抽象方法暴露出去,由其子类SubTime实现runcode()的具体功能。

三、装饰设计模式:

    当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能,那么自定义的该类成为装饰类

    装饰类通常会通过构造方法接收被装饰的对象,并基于被装饰的对象的功能,提供更强的功能

class Person{

    public void eat(){

       System.out.println("吃饭!");

    }

}

class SuperPerson{

    private Personp;

    SuperPerson(Person p){

       this.p=p;

    }

    public void eat(){

       System.out.println("开胃酒!");

       p.eat();

       System.out.println("甜点!");

       System.out.println("抽根烟!");

    }

}

class Test{

    public static void main(String[] args) {

       Person p=new Person();

       p.eat();

       SuperPerson sp=new SuperPerson(p);

       sp.eat();

    }

}

如上代码,Person p的eat()方法只有吃饭!一个功能,将Person p 传入SuperPerson中基于Person p的eat()方法,创建了一个SuperPerson sp的eat()方法,不仅具有吃饭!功能,还有开胃酒!甜点!抽根烟等功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值