单例模式确保一个类只有一个实例,并且提供一个全局访问点
单例模式有多种实现方式,不同的实现方式有不同的特点
//多线程不安全的单例模式
//!!!错误的单例,不建议使用
public class Singletion{
private static Singletion instance;
private Singletion(){
}
public static Singletion getInstance(){
if(instance == null){
instance = new Singletion();
}
return instance;
}
}
//非延迟实例化的单例
//会在程序运行时就创建Singleton对象,占用空间
public class Singleton{
private static Singletion instance = new Singleton();
private Singletion(){
}
public static Singletion getInstance(){
return instance;
}
}
//方法同步的单例,效率低
//!!!不建议使用
public class Singleton{
private static Singletion instance = new Singleton();
private Singletion(){
}
public synchronized static Singletion getInstance(){
if(instance == null){
instance = new Singletion();
}
return instance;
}
}
//"双重检查加锁"的单例模式
//推荐使用
public class Singleton{
//volatile保证,某个线程改变instance的值时对其他线程可见
private volatile static Singletion instance的值时对其他线程可见 = new Singleton();
//私有的构造器保证,不能直接使用new进行创建
private Singletion(){
}
public static Singleton getInstance(){
//先判断instance是否为null,再进入同步块,减少同步时间
if(instance == null){
//进行同步
sychronized(Singleton.class){
//只有一个线程能进行该部分,如果此时instance仍然为空,则创建对象
if(instance == null){
instance = new Singletion();
}
}
}
return instance;
}
}
命令模式将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。
实现带一个插槽的遥控器对电灯进行控制
//命令接口
public interface Command {
public void execute();
}
//电灯类,有开和关两个方法
public class Light {
public void on() {
System.out.println("Light on");
}
public void off() {
System.out.println("Light off");
}
}
//电灯控制类,继承自Command
public class LightOnCommand implements Command{
private Light light;
//构造器中传入某个电灯,并记录在实例变量中
//一旦调用execute(),就由这个电灯对象成为接收者,负责接受请求
public LightOnCommand(Light light){
this.light = light;
}
@Override
public void execute() {
light.on();
}
}
//简单遥控器(调用者)
public class SimpleRemoteControl {
//有一个插槽持有命令,而这个命令控制着一个装置
Command slot;
public SimpleRemoteControl(){
}
//用于设置插槽控制的命令
//如果客户想要改变遥控器按钮的行为,可以多次调用这个方法
public void setCommand(Command command) {
slot = command;
}
//当按下按钮时,这个方法就会被调用
//并执行插槽对应命令的execute方法
public void buttonWasPressed() {
slot.execute();
}
}
//本类是命令模式的客户
public class RemoteControlTest {
public static void main(String[] args) {
//创建一个调用者,之后会传入一个命令给他
SimpleRemoteControl remoteControl = new SimpleRemoteControl();
//这个电灯对象就是请求的接收者
Light light = new Light();
//创建一个命令,并把接收者传给他
LightOnCommand command = new LightOnCommand(light);
//把命令穿给调用者
remoteControl.setCommand(command);
//模拟按下按钮
remoteControl.buttonWasPressed();
}
}
按照下图实现遥控器及其对应的命令模式
//接收者:灯
public class Light {
String type;
public Light(String type) {
this.type = type;
}
public void on() {
System.out.println(type + " Light on");
}
public void off() {
System.out.println(type + " Light off");
}
}
//接收者:音响
public class Stereo {
String type;
public Stereo(String type) {
this.type = type;
}
public void on(){
System.out.println(type + " Stereo on");
}
public void off(){
System.out.println(type + " Stereo off");
}
public void setCd(){
System.out.println(type + " Stereo setCd");
}
public void setDvd(){
System.out.println(type + " Stereo setDvd");
}
public void setRadio(){
System.out.println(type + " Stereo setRadio");
}
public void setVolume(int volume){
System.out.println(type + " Stereo setVolume = " + volume);
}
}
//命令接口
public interface Command {
public void execute();
public void undo();
}
//表示该开关暂时不对应命令
public class NoCommand implements Command{
@Override
public void execute() {
System.out.println("Nothing to do");
}
@Override
public void undo() {
System.out.println("Nothing to do");
}
}
//打开灯的命令
public class LightOnCommand implements Command{
private Light light;
//构造器中传入某个电灯,并记录在实例变量中
//一旦调用execute(),就由这个电灯对象成为接收者,负责接受请求
public LightOnCommand(Light light){
this.light = light;
}
@Override
public void execute() {
light.on();
}
@Override
public void undo() {
light.off();
}
}
//关闭灯的命令
public class LightOffCommand implements Command{
private Light light;
//构造器中传入某个电灯,并记录在实例变量中
//一旦调用execute(),就由这个电灯对象成为接收者,负责接受请求
public LightOffCommand(Light light){
this.light = light;
}
@Override
public void execute() {
light.off();
}
@Override
public void undo() {
light.on();
}
}
//打开音响并放入CD
public class StereoOnWithCDCommand implements Command{
private Stereo stereo;
public StereoOnWithCDCommand(Stereo stereo) {
this.stereo = stereo;
}
@Override
public void execute() {
stereo.on();
stereo.setCd();
stereo.setVolume(11);
}
@Override
public void undo() {
stereo.off();
}
}
//关闭音响的命令
public class StereoOffCommand implements Command{
private Stereo stereo;
public StereoOffCommand(Stereo stereo) {
this.stereo = stereo;
}
@Override
public void execute() {
stereo.off();
}
@Override
public void undo() {
stereo.on();
stereo.setCd();
stereo.setVolume(11);
}
}
//调用者:遥控器
public class RemoteControl {
Command[] onCommands;
Command[] offCommands;
command undoCommand;
//在构造方法中实例化并初始化这两个开关数组
public RemoteControl() {
onCommands = new Command[7];
offCommands = new Command[7];
Command noCommand = new NoCommand();
for (int i = 0; i < 7; i++) {
onCommands[i] = noCommand;
offCommands[i] = noCommand;
}
undoCommand = noCommand;
}
//setCommand有三个参数,分别是插槽号,和开关命令
public void setCommand(int slot, Command onCommand, Command offCommand) {
onCommands[slot] = onCommand;
offCommands[slot] = offCommand;
undoCommand = offCommands[slot];
}
//当开关按下时,硬件就会负责调用下面两个方法
public void onButtonWasPushed(int slot) {
onCommands[slot].execute();
}
public void offButtonWasPushed(int slot) {
offCommands[slot].execute();
}
public void undoButtonWasPushed() {
undoCommand.undo();
}
}
//客户
public class RemoteLoader {
public static void main(String[] args) {
//创建遥控器(调用者)
RemoteControl remoteControl = new RemoteControl();
//创建家具(接收者)
Light livingRoomLight = new Light("Living room");
Light kitchenLight = new Light("Kitchen light");
Stereo stereo = new Stereo("Living room");
//创建开关命令
LightOnCommand livingRoomLightOnCommand = new LightOnCommand(livingRoomLight);
LightOffCommand livingRoomLightOffCommand = new LightOffCommand(livingRoomLight);
LightOnCommand kitchenLightOnCommand = new LightOnCommand(kitchenLight);
LightOffCommand kitchenLightOffCommand = new LightOffCommand(kitchenLight);
StereoOnWithCDCommand livingRoomStereoOnCommand = new StereoOnWithCDCommand(stereo);
StereoOffCommand livingRoomStereoOffCommand = new StereoOffCommand(stereo);
//为调用者设置命令,(将命令放入遥控器插槽)
remoteControl.setCommand(0, livingRoomLightOnCommand, livingRoomLightOffCommand);
remoteControl.setCommand(1, kitchenLightOnCommand, kitchenLightOffCommand);
remoteControl.setCommand(2, livingRoomStereoOnCommand, livingRoomStereoOffCommand);
//按动遥控器开关
remoteControl.onButtonWasPushed(0);
remoteControl.offButtonWasPushed(0);
remoteControl.undoButtonWasPushed();
remoteControl.onButtonWasPushed(1);
remoteControl.offButtonWasPushed(1);
remoteControl.onButtonWasPushed(2);
remoteControl.offButtonWasPushed(2);
remoteControl.onButtonWasPushed(3);
remoteControl.offButtonWasPushed(3);
}
}
//执行结果
Living room Light on
Living room Light off
Living room Light on ------------> undo
Kitchen light Light on
Kitchen light Light off
Living room Stereo on
Living room Stereo setCd
Living room Stereo setVolume = 11
Living room Stereo off
Nothing to do
Nothing to do
适配器模式将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。
将枚举器(老的迭代器)适配迭代器
//迭代器
public interface Iterator(){
public boolean hasNext(){
//判断是否有下一个元素
}
public Object next(){
//获取下一位元素
}
public boolean remove(){
//删除元素
}
}
//枚举器
public interface Enumeration(){
public boolean hasMoreElements(){
//判断是否有下一个元素
}
public Object nextElement(){
//获取下一位元素
}
}
//枚举器转换迭代器的适配器
public class EnumerationIteratorAdapter(){
private Enumeration enumeration;
public EnumerationIteratorAdapter(Enumeration enumeration){
this.enumeration = enumeration;
}
public boolean hasNext(){
//判断是否有下一个元素
enumeration.hasMoreElements();
}
public Object next(){
//获取下一位元素
enumeration.nextElement();
}
public boolean remove(){
//删除元素
//由于Enumeration没有删除元素的操作,所以抛出异常
throw new UnsupportedOperationException();
}
}
类适配器通过多继承类的方式对被适配者和适配者进行适配,而对象适配器则是使用接口和组合的方式
外观模式提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。
不要让太多类耦合在一起,免得系统中一部分,会影响到其他部分
就任何对象而言,在该对象的方法内,只应该调用属于一下范围的方法: