关于设计模式的整理

设计原则

  • 封装变化。
  • 针对接口编程,不针对实现变成。
  • 多用组合,少用继承。
  • 使交互对象之间松耦合。
  • 对扩展开放,对修改关闭。
  • 依赖抽象,不依赖具体。

设计模式


策略模式

  • 定义:

封装算法族,让它们可以互相替换,或者组合到一起,让算法的变化独立于算法的客户。

  • 应用场景:

假设有一个父类派生出10个子类,而当其中有5个子类需要添加一个算法A时,把这个功能添加到父类显然不合适,因为另外5个并不需要算法A。逐个给这5各类添加该算法则造成代码冗余严重。那给这5个类与父类之间再添加一个父类怎么样?看起来也可以,但如果再给这5各类其中3个添加算法B呢?这样的扩展对整体结构来说很不灵活。这个时候策略模式派上用场了。

  • 实现方式:

我们可以把算法A、算法B等封装起来,并且继承同一个interface,在父类中声明该interface的引用,子类们可以根据自己的需求对interface实例化。通过这样的算法族组合起来,使结构更具有弹性。


观察者模式

  • 定义:

在对象之间定义一对多依赖,使改变一个对象的状态,其他对象都会收到通知并自动更新。

  • 应用场景:

普遍应用于事件传递,如广播和UI事件监听等。被观察者无需关心谁加入观察,完全由观察者决定是否加入观察的行列。

  • 实现方式:

被观察者定义了interface,并在自身状态发生改变时调用interface通知观察者。而对象要成为观察者只需要实例化interface,并把它交给被观察者。


装饰者模式

  • 定义:

动态的将责任附加到对象上。这是一种有别于继承的扩展功能的方式。

  • 应用场景:

当父类A派生的子类种类非常繁多,而不同子类之间又存在各种相同特性的混合关系,如BC、CD、BD等。可以把这些特性独立封装起来,如B、C、D类,使子类的数量压缩到最少,根据不同的需求把封装的特性附加到子类上。

  • 实现方式:

class A {
		public void do() {
			return 0.1;
		};
	}
	class B extends A {
		A a;
		public B (A a) {
			this.a = a;
		}
		public void do() {
			return 0.1 + a.do();
		};
	}
	class C extends A {
		A a;
		public C (A a) {
			this.a = a;
		}
		public void do() {
			return 0.2 + a.do();
		};
	}
	public static int main(String args[]) {
		A a = new A();
		a = new B(a);	//用B装饰a
		a = new C(a);	//用C装饰a
	}

 

工厂模式

  • 定义:

定义了一个创建对象的接口,由子类决定要实例化的类是哪一个,让类的实例化推迟到子类。通常包括工厂方法和抽象工厂方法,前者主要以继承方式让子类决定产品类型(也包括简单工厂,即不需要派生子类,直接提供产品),后者则通过接口方式组合各种产品对象。

  • 应用场景:

当只有在运行时才知道需要实例化的是哪个类,我们就可以把这种类型判断和对象创建采用工厂方法封装起来。工厂方法用于创建具体的产品,抽象工厂用于定义整个产品家族的创建接口。而后者派生出的具体工厂则是工厂方法。

  • 实现方式:

简单工厂方法

public static class Factory {
		public static A createObj(int type) {
			if (type == 0) return new B();		//B extends A
			else if (type == 1) return new C();	//C extends A
		}
	}

工厂方法

public abstract class Factory {
		public A orderObj(int type) {
			A a = createObj(type);
			a.init();
			a.doSomething();
			return a;
		}//由派生的具体工厂决定创建类型
		abstract A createObj(int type);
		//其他方法
	}

 

抽象工厂方法

public interface Factory {
	public A createA();
	public B createB();
}
public class MyFactory implements Factory {
	public A createA() { return new A(); }
	public B createB() { return new B(); }
}

单件模式

  • 定义:
确保一个类只有一个实例,并提供一个全局访问点。
  • 应用场景:
有些类只需要一个实例能更好的控制程序,多了反而会造成程序行为异常、资源使用过量、或不一致等问题。如线程池、缓存、对话框、日志对象等。
  • 实现方式:

public class Singleton {
	private static Singleton instance;
	//构造方法设为私有,不对外开放
	private Singleton() {
	}
	//全局访问点
	public static Singleton getInstance(){
		if (instance == null) {
			//延迟实例化对象(如果存在多线程调用则不建议这样做,以免因不同步而创建了多个对象。应改成在定义时直接实例化对象)
			instance = new Singleton();
		}
		return instance;
	}
}

命令模式

  • 定义:
把“请求”封装成对象,以便使用不同的请求、对列或者日志来参数化其他对象。同时也支持可撤销的操作。
  • 应用场景:
 假设有许许多多的动作执行者,它们都有不同的动作行为,如果要给它们发送动作请求,则需要许许多多的动作请求者。通过命令模式,我们可将“动作请求者”从“动作执行者”对象中解耦。
  • 实现方式:

//动作执行者
public class Actor {
	public void do() {
		//do something
	}
	public void reset() {
		// reset state
	}
}
//封装命令
public interface Command {
	public void execute();
	public void undo();
}
public class ActorCommand implements Command {
	Actor a;
	public ActorCommand(Actor a) {
		this.a = a;
	}
	public void execute() {
		a.do();
	}
	public void undo() {
		a.reset();
	}
}
//动作请求者
public class RemoteControl {
	Command cmd;
	public void setCommand(Command cmd) {
		this.cmd = cmd;
	}
	public void doCommand() {
		cmd.execute();
	}
	public void cancel() {
		cmd.undo();
	}
}
public static void main(String[] args) {
	RemoteControl remote = new RemoteControl();
	Actor a = new Actor();
	ActorCommand cmd = new ActorCommand(a);
	remote.setCommand(cmd);//可设置不同请求命令
	remote.doCommand();
	remote.cancel();
}

适配器模式

  • 定义:
将一种接口转换成客户期望的另一种接口。让原本不兼容的类可以合作无间。
  • 应用场景:
假设有一个软件系统有个旧模块需要改为新厂商提供的模块,当新厂商提供的模块与系统的接口匹配。采用适配器模式对接口进行转换,软件系统和新的模块都不用做任何修改就能实现匹配。
  • 实现方式:
public interface A {
	public void walk();
	public void run();
}
public interface B {
	public void walk();
	public void fly();
}
//让B接口适配A接口
public class BAdapter implements A {
	B b;
	public BAdapter(B b) {
		this.b = b;
	}
	public void walk() {
		b.walk();
	}
	public void run() {
		b.fly();	
	}
}
  • 外观模式
还有另一种实现方式与适配器类似的模式,但它转换接口的目的是简化接口--外观模式。外观模式提供一个统一的接口用来访问子系统中的一群接口。它定义了高层次的接口,让子系统更容易使用。
  • 对比
它们看起来是否与装饰者模式有点相似?不妨对它们3个进行对比:

模式意图
装饰者不改变接口,但加入行为责任
适配器将一个接口转成另一个接口
外观让接口更简单


待续……



  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值