java—单例模式

1)需求
比如,任务管理器打开后,再次打开不会打开新窗口,还是刚才的窗口
要点:
某个类只有一个实例
它必须自行创建这个实例;
必须向整个系统提供这个实例;
2)实现
首先是未实现单例模式的效果

package window;

public class TaskMangerWindow {
	public TaskMangerWindow() {
		System.out.println("任务管理器创建");
		
	}
	public void show() {
		System.out.println("任务管理器显示");
	}

}
package singleton1;
import window.TaskMangerWindow;
public class Main {
	public static void click() {
		TaskMangerWindow tmw=new TaskMangerWindow();
		tmw.show();
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        click();
        click();
	}

}


实验结果:任务管理器创建
任务管理器显示
任务管理器创建
任务管理器显示

显然创建了俩个页面。

最原始的单例模式
用静态变量实现,俩次点击只创建一个对象。

package singleton2;
import window.TaskMangerWindow;
 class SystemConf{
	 public static TaskMangerWindow tmw=new TaskMangerWindow();
	
}
public class Main {
	public static void click() {
		TaskMangerWindow tmw=SystemConf.tmw;//点击时创建了一个静态的对象
		tmw.show();
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		click();
		click();

	}

}

结果:
任务管理器创建
任务管理器显示
任务管理器显示

首次改进
由于最原始的多了一个SystemConf类,可以把实现静态对象直接放在原来的类中,即在类中即实现了一个自己静态的对象。

package window;

public class TaskMangerWindow {
	public static TaskMangerWindow tmw=new TaskMangerWindow();
	
	public TaskMangerWindow() {
		System.out.println("任务管理器创建");
		
	}
	public void show() {
		System.out.println("任务管理器显示");
	}

}
package singleton2;
import window.TaskMangerWindow;
 class SystemConf{
	 
}
public class Main {
	public static void click() {
		TaskMangerWindow tmw=TaskMangerWindow.tmw;
		tmw.show();
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		click();
		click();

	}

}


结果:
任务管理器创建
任务管理器显示
任务管理器显示

再次改进
首次改进后代码仍然有以下缺陷:
(1)虽然用户可以用TaskMangerWindow.tmw使用任务管理器窗口对象,但是也可以通过new来实例化。
(2)在一般情况下将成员变量定义为私有的,但此处的TaskMangerWindow中的成员tmw是public的。

改进方法:在第一个问题中只需将构造函数定义为私有的;第二个问题只需将tmw成员定义为私有,然后用一个函数获取。

package window;

public class TaskMangerWindow {
	private static TaskMangerWindow tmw=new TaskMangerWindow();
	public static TaskMangerWindow get() {
		return tmw;
	}
	
	private TaskMangerWindow() {
		System.out.println("任务管理器创建");
		
	}
	public void show() {
		System.out.println("任务管理器显示");
	}

}
package singleton2;
import window.TaskMangerWindow;

public class Main {
	public static void click() {
		TaskMangerWindow tmw=TaskMangerWindow.get();
		tmw.show();
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		click();
		click();

	}

}

2利用继承和多态扩充程序功能

1)需求简介
假如编写了一个图像处理文件,能够显示一副图片。

package imageprocess;

public class ImageProcessor {
	public void show() {
		System.out.println("显示一幅图片");
	}

}
package imageprocess;

public class Main1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ImageProcessor ip=new ImageProcessor();
		ip.show();

	}

}

要在ImageProcessor类中在显示图片之前加一个去噪声的操作,不改变ImageProcessor类的情况下实现。

实现方法:继承ImageProcessor类,show()函数重写一下,加入新操作

任务管理器中怎么查看JAva中的线程 java 任务管理器_任务管理器中怎么查看JAva中的线程

package imageprocess;

public class ImageProcessor {
	public void show() {
		System.out.println("显示一幅图片");
	}

}
package imageprocess;
import newimageprocessor.NewImageProcessor;
import noiseope.NoiseOpe;
public class Main1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		NewImageProcessor ip=new NewImageProcessor(new NoiseOpe());
		ip.show();

	}

}
package newimageprocessor;
import imageprocess.ImageProcessor;
import noiseope.NoiseOpe;
public class NewImageProcessor extends ImageProcessor {
	private NoiseOpe no;
	public NewImageProcessor(NoiseOpe a) {
		this.no=a;
	}
	public void show() {
		no.work();
		super.show();
	}

}
package noiseope;

public class NoiseOpe {
	public void work() {
		System.out.println("去噪声");
	}

}
结果:
去噪声
显示一幅图片

出现的问题
NewImageProcessor类中的参数只能是NoiseOpe类型,即只能由这个模块提供服务。写了新模块或NoiseOpe改进为NewNoiseOpe就无法传入
改进
利用多态性解决这个问题,定义一个接口INoiseOpe,要求无论NoiseOpe还是NewNoiseOpe都实现这个接口就可以了。