两个简单的设计模式

[align=center][b]单例设计模式[/b][/align]
单例设计模式原理(保证对象唯一性):
1、 为了避免其他程序过多建立该对象,铁饭碗禁止其他程序建立该类对象
2、 还为了让其他程序可以访问到该类对象,只好在本类中自定义一个对象
3、 为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式
对应的设计步骤:
1、 将构造方法私有化
2、 在类中创建一个本类对象
3、 提供一个方法可以获取到该对象
事例:
public class SimpleDemo 
{
public static void main(String[] args)
{
Student st1 = Student.getInstance();
Student st2 = Student.getInstance();
System.out.println(st1 == st2);
}
}
class Student
{//这个是先初始化,饿汉式
private Student() {}
//而静态方法里面操作的都是静态的变量且st是成员变量所有设成private static
private static Student st = new Student();
//由于无法通过对象来访问这个方法,所以设成静态的
public static Student getInstance() {
return st;
}
}

单例的另外一种写法:
class Student
{//这个是后初始化,对象的延时加载,懒汉式
private static Student st = null;
private Student() {}
public static Student getInstance() {
if (st == null) //******* A B
st = new Student();
return st;
}
}

如果是懒汉式的话,就存在着多线程的问题,可能会在***号处出现线程的交替,可能会产生两个对象
使用的解决方法有双重决断,在程序员面试的时候考的比较多,但实际开发中用饿汉式,安全而且代码量少
class Student
{
private static Student st = null;
private Student() {}
public static Student getInstance() {
if (st == null) {
synchronized(Student.class) {
if (st == null) {
st = new Student();
}
}
}
return st;
}
}

此处的synchronized()所使用的参数(即锁对象)是方法所在类的字节码文件对象,是因为所操作的成员变量是static的,默认使用的锁是Student.class,因此这样才能使其达到同步的效果,而且没有安全隐范。

[align=center][b]模版方法模式[/b][/align]
应用举例:
/*
需求:编写一个获取程序运行时间的程序
方法:使用开始运行时间减去结束运行时间
获取时间:System.currentTimeMillis()
什么是模版方法呢?
在定义功能时,功能的一部分是确定的,但是有一部分是不确定的,而确定的部分在使用不确定的部分,那么这时就将不确定的部分暴露出去,由该类的子类去完成。
*/
class GetTime
{
public void getTime() {
long start = System.currentTimeMillis();
/****中间的代码不确定****/
for(int i = 1; i < 1000; i++) {
System.out.print(i);
}
/****中间的代码不确定****/
long end = System.currentTimeMillis();
System.out.println("\n毫秒:" + (end - start));
}
}
public class TemplateDemo
{
public static void main(String[] args)
{
GetTime gt = new GetTime();
gt.getTime();
}
}

由于GetTime类中间的代码是不确定的,所以我们用另外一个方法将其封装起来,增加runCode()方法
class GetTime
{
public void getTime() {
long start = System.currentTimeMillis();
/****中间的代码不确定****/
runCode();
/****中间的代码不确定****/
long end = System.currentTimeMillis();
System.out.println("\n毫秒:" + (end - start));
}
public void runCode() {
for(int i = 1; i < 1000; i++) {
System.out.print(i);
}
}
}

一般是不建议修改已有的代码,如果还有另外的一段代码需要获取运行时间,我们用写另外一个类继承GetTime类
class SubClass extends GetTime
{
public void runCode() {
for(int i = 1; i < 4000; i++) {
System.out.print(i);
}
}
}

此处我们只需要重写一个runCode()方法就能够获取相应代码的运行时间,增加了程序的复用性
由于GetTime类只实现一个功能,而且是固定的,此处我们可以让别人不能重写我们的getTime()方法,而runCode()是里面是不需要写实现的,那我们定义其为静态方法,而类相应的也要改成静态的,修改后的GetTime类如下:
abstract class GetTime
{
public final void getTime() {
long start = System.currentTimeMillis();
/****中间的代码不确定****/
runCode();
/****中间的代码不确定****/
long end = System.currentTimeMillis();
System.out.println("\n毫秒:" + (end - start));
}
public abstract void runCode();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值