java常用设计模式学习总结

常用设计模式归纳:

创建型:单例模式,工厂方法模式等等

结构型:静态代理模式,动态代理模式,装饰者模式,适配器模式,桥接模式

行为型:观察者模式,命令模式,责任链模式,状态模式,访问者模式

1.单例模式

应用场景:顾名思义,自始至终都操作的是同一个对象的时候,需要用单例模式

​/**
 * 单例懒汉式(比较常用)
 */
public class SingletonPatternLazy {
	
	private SingletonPatternLazy() {}
	
	public static SingletonPatternLazy getInstance () {
		return SingletonPatternInstance.singletonPatternLazy;
	}
	
	private static class SingletonPatternInstance {
		final static SingletonPatternLazy singletonPatternLazy = new SingletonPatternLazy();
	}
	
	public static void main(String[] args) {
		SingletonPatternLazy instance1 = SingletonPatternLazy.getInstance();
		SingletonPatternLazy instance2 = SingletonPatternLazy.getInstance();
		
		System.out.println(instance1 == instance2);
	}

}

​/**
 * 单例饿汉式(比较常用)
 */
public class SingletonPattern {
	
	private SingletonPattern() {}
	
	private final static SingletonPattern singletonPattern = new SingletonPattern();
	
	public static SingletonPattern getInstance() {
		return singletonPattern;
	}

	public static void main(String[] args) {
		SingletonPattern instance1 = SingletonPattern.getInstance();
		SingletonPattern instance2 = SingletonPattern.getInstance();
		System.out.println(instance1 == instance2);
	}

}

单例模式优化升级版(推荐)

/**
 * 单例懒汉式(最标准的单例模式)
 */
public class SingletonPatternLazy {

	private static SingletonPatternLazy instance = null;

	private SingletonPatternLazy() {
	}

	public static SingletonPatternLazy getInstance() {
		if (instance == null) {
			newInstance();
		}
		return instance;
	}

	private synchronized static void newInstance() {
		if (instance == null) {
			instance = new SingletonPatternLazy();
		}
	}

	public static void main(String[] args) {
		
		for(int i = 0; i < 100; i ++) {
			new Thread(() -> System.out.println(SingletonPatternLazy.getInstance())).start();
		}

	}

}

 

2.工厂方法模式

应用场景:

当我们需要获取同一规范下的各个不同实现的对象,并且再获取这些对象的时候比较麻烦的情况下,可以考虑使用工厂模式。

在扩展规范的实现的时候,同时又需要去扩展工厂,为了便于扩展,适应于开闭原则,因此产生了工厂方法模式,即一个工厂只创建规范下的一个实现的对象。

不同的对象的创建对应不同的工厂,那么这些不同的工厂就可以抽象出一个模板出来,或者提前定义一个接口出来。

​
/*
 * 需要被使用工厂创建的source
 */
//Person规范
public interface Person {
	void work();
}

//Person的一个具体实现,Programmer
public class Programmer implements Person {
	@Override
	public void work() {
		System.out.println("程序员work");
	}
}

/*
 * 工厂相关
 */
//工厂规范
public interface PersonFactory {
	Person getInstance();
}

//工厂规范的一个实现ProgrammerFactory 
public class ProgrammerFactory implements PersonFactory {

	private Programmer programmer;
	
	@Override
	public Person getInstance() {
		if(programmer == null) {
			newInstance();
		}
		return programmer;
	}
	
	private synchronized void newInstance() {
		if(programmer == null) {
			programmer = new Programmer();
		}
	}

}

/*
 * 工厂方法模式测试
 */
public class PersonFactoryBuilder {

	
	public static PersonFactory build(Class clazz) {
		try {
			return clazz.newInstance();
		} catch (InstantiationException | IllegalAccessException e) {
			throw new RuntimeException(e);
		}
	}
	
	public static void main(String[] args) {
		PersonFactory personFactory = PersonFactoryBuilder.build(ProgrammerFactory.class);
		for(int i = 0; i < 100; i ++) {
			new Thread(() -> System.out.println(personFactory.getInstance())).start();
		}
		
	}
	
}

3.静态代理模式

应用场景:用的不太多,一般用动态代理

//被代理的规范
public interface IPerson {
	void doSome();
}

//被代理的实现
public class Person implements IPerson{
	
	public void doSome(){
		System.out.println("基本功能...");
	}
	
}

//代理类
public class PersonProxy implements IPerson{
	
	private IPerson person;
	
    //构造需要一个被代理的对象
	public PersonProxy(IPerson person){
		this.person = person;
	}
	
	public void doSome(){
		before();
		person.doSome();
		after();
	}
	
	public void before(){
		System.out.println("before...");
	}
	
	public void after(){
		System.out.println("after...");
	}
}

/*
 *测试静态代理
 */
public static void testProxy(){
	IPerson proxy = new PersonProxy(new Person());
	proxy.doSome();
}

4.动态代理模式

应用场景:spring的aop底层就是基于动态代理,当我们需要横向且动态对程序进行扩展,即扩展任意对象的方法的时候,可以用到动态代理

jdk动态代理

//被代理规范
public interface ISource {
	void doSome(String inputSome);
}

//被代理的实现
public class SourceImpl implements ISource{
	
	public void doSome(String inputSome){
		System.out.println("基本功能,输出内容:" + inputSome);
	}
	
}

//创建一个简单的代理内容的实现类
public class BeforeAfterInvocationHandler implements InvocationHandler {
	
	private Object source;

	public BeforeAfterInvocationHandler(Object source){
		this.source = source;
	}
	
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		before();
		method.invoke(source, args);
		after();
		return null;
	}
	
	
	public void before(){
		System.out.println("------执行before-------");
	}
	
	public void after(){
		System.out.println("------执行after-------");
	}
	
	/**
	 * 获取t对象的代理对象
	 * @param t 被代理的对象
	 * @return 返回代理对象
	 */
	@SuppressWarnings("all")
	public static  T getProxy(T t){
		BeforeAfterInvocationHandler invocationHandler = new BeforeAfterInvocationHandler(t);
		Class[] interfaces = t.getClass().getInterfaces();
		T tProxy = (T) Proxy.newProxyInstance(invocationHandler.getClass().getClassLoader(), interfaces, invocationHandler);
		return tProxy;
	}
	
}

//测试动态代理
public static void testDynamicProxy(){
	ISource source = new SourceImpl();
	BeforeAfterInvocationHandler.getProxy(source).doSome("这是动态代理测试的输出内容");
}

cglib动态代理

依赖cglib:


    cglib
    cglib
    3.3.0

//被代理类
public class Programmer {
	
	public String getUsername() {
		return "lucy";
	}

	public void doSome() {
		System.out.println("程序员doSome()");
	}

}

//代理类处理器
public class CGlibProxyHandler implements MethodInterceptor {
	
	public Object createProxy(Object source){
		Enhancer enhancer = new Enhancer();
		enhancer.setCallback(this);
		enhancer.setSuperclass(source.getClass());
		return enhancer.create();
	}

	@Override
	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
		before(obj, args);
		Object object = proxy.invokeSuper(obj, args);
		after(object);
		return object;
	}
	
	//前置增强
	private void before(Object obj, Object[] args) {
		System.out.println("before:" + obj.getClass().getSuperclass().getName());
	}
	
	//后置增强
	private void after(Object object) {
		System.out.println("after:" + JSONObject.toJSONString(object));
	}
	
	@SuppressWarnings("unchecked")
	public static  T getProxy(T t){
		CGlibProxyHandler handler = new CGlibProxyHandler();
		return (T) handler.createProxy(t);
	}

}

//测试
public static void main(String[] args) {
	Programmer proxy = CGlibProxyHandler.getProxy(new Programmer());
	String name = proxy.getUsername();
	System.out.println(name);
	proxy.doSome();
}

 

5.装饰者模式

应用场景:当我们需要动态的横向扩展程序的时候,即动态的扩展某一对象的方法,可以用装饰者模式

注意与动态代理的区别:

动态代理是对任意对象的方法扩展,但扩展的内容是固定不变的

装饰者模式是对某一个对象的方法扩展,扩展的内容是可以动态变化的

//被装饰的规范
public interface IPerson {
	void doSome();
}

//被装饰规范的实现
public class PersonImpl implements IPerson {

	public void doSome() {
		System.out.println("吃饭功能....");
	}

}

//抽象装饰器
public abstract class PersonDecorator implements IPerson {
	
	private IPerson person;
	
	public PersonDecorator(IPerson person){
		this.person = person;
	}
	
	//调用当前构造中接受的person实例的dosome()
	public void doSome() {
		person.doSome();
	}

}

//装饰器Student
public class Student extends PersonDecorator {
	
	//构造需要提供一个person实例
	public Student(IPerson person){
		//把构造参数交给父类
		super(person);
	}
	
	public void doSome(){

		/*
		 *首先,调用父类的doSome()
		 *然后,父类中又调用当前构造中接受的person实例的dosome()
		 */
		super.doSome();
		System.out.println("学习功能...");
	}
}

//装饰器Worker
public class Worker extends PersonDecorator {
	
	public Worker(IPerson person){
		super(person);
	}
	
	public void doSome(){
		super.doSome();
		System.out.println("工作功能...");
	}

}

//测试装饰者模式
public static void testDecorator(){
	//基本的person
	PersonImpl person = new PersonImpl();
	System.out.println("--------------person: --------------");
	//基本的person所做的事
	person.doSome();

	//被worker装饰过的基本person
	Worker worker = new Worker(person);
	System.out.println("--------------worker: --------------");
	//被worker装饰过的person所做的事
	worker.doSome();

	//被学生装饰过的worker
	Student student = new Student(worker);
	System.out.println("--------------student: --------------");
	//被学生装饰过的worker所做的事
	student.doSome();
}

6.适配器模式

应用场景:比如应用中有一个类A,还有一个规范,且规范的某一个或多个方法具有和类A相同的实现,因此就不需要再单独去实现这些方法了,可以新增一个抽象适配器类,直接去继承类A,然后定义新的抽象规范

//被适配者
public class Animal {
	public void eat() {
		System.out.println("eat()*************************");
	}
}

//需要适配Animal的接口
public interface IPerson {	
	public void doWork();	
}

//适配器
public class AnimalAdpter extends Animal implements IPerson {

	@Override
	public void doWork() {
		before();
		super.eat();
		after();
	}
	
	private void before() {
		System.out.println("AnimalAdpter.before()*************************");
	}
	
	private void after() {
		System.out.println("AnimalAdpter.after()*************************");
	}
	
	public static void main(String[] args) {
		IPerson person = new AnimalAdpter();
		person.doWork();
	}

}


7.桥接模式

应用场景:当我们需要操作规范,但又无法固定实现的时候,可以提供一组规范,让客户方来实现,我们操作的时候只需注入客户方的实现对象,这种模式就是桥接模式,例如:jdbc定义了驱动规范,各个数据库厂商提供不同的驱动实现

//需要桥接的规范IBridgeAble
public interface IBridgeAble {	
	public void doSome(String arg0, String arg1);	
}

//定义对该规范的伪实现BridgeAble
public class BridgeAble implements IBridgeAble {
	
	private IBridgeAble bridgeAble;
	
	public BridgeAble(IBridgeAble bridgeAble){
		this.bridgeAble = bridgeAble;
	}

	public void doSome(String arg0, String arg1) {	
		bridgeAble.doSome(arg0, arg1);
	}

}

//A客户方提供的实现BrideAbleImplA
public class BrideAbleImplA implements IBridgeAble{

	public void doSome(String arg0, String arg1) {
		System.out.println("BrideAbleImplA.arg0: " + arg0 + " BrideAbleImplA.arg1: " + arg1);
	}

}

//B客户方提供的实现BrideAbleImplB
public class BrideAbleImplB implements IBridgeAble{

	public void doSome(String arg0, String arg1) {
		System.out.println("BrideAbleImplB.arg0: " + arg0 + " BrideAbleImplB.arg1: " + arg1);
	}

}

//测试桥接模式
public static void testBridge(){
	BridgeAble bridge = new BridgeAble(new BrideAbleImplA());
	bridge.doSome("A", "A1");
}

8.观察者模式

应用场景:观察者模式略微难理解,但十分重要,例如监听器就需要使用观察者模式来实现

//定义观察者规范
public interface IObserver {
	void operate();
}

//观察者ObserverOne,额外提供了单例模式获取对象,通常情况观察者,都是单例的
public class ObserverOne implements IObserver {
	@Override
	public void operate() {
		System.out.println("观察者1观察到了变化");
	}
}

//观察者ObserverTwo
public class ObserverTwo implements IObserver {
	@Override
	public void operate() {
		System.out.println("观察者2观察到了变化");
	}
}

//抽象的被观察者BeObserver
public abstract class BeObserver {
	
	private Set observers;
	
	public BeObserver(Set observers) {
		this.observers = observers;
	}
	
	public abstract void doSome();

	protected void notifyObserver() {
		if(observers != null) {
			observers.forEach(observer -> observer.operate());			
		}
	}

}

//被观察者实现DefaultBeObserver
public class DefaultBeObserver extends BeObserver {
	
	public DefaultBeObserver(Set observers) {
		super(observers);
	}

	@Override
	public void doSome() {
		super.notifyObserver();
		System.out.println("doSome()***********");
	}

}

//测试观察者模式
public static void testObserver(){
	HashSet observers = new HashSet();
	observers.add(new ObserverOne());
	observers.add(new ObserverTwo());
	new DefaultBeObserver(observers).doSome();
}

9.监听器

//事件
public class Event {
	public void print() {
		System.out.println("当前时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()));
	}
}

//暴露监听器接口
public interface Listener {
	void onEvent(Event e);
}

//需要客户编写的监听器实现
public class ListenerImpl implements Listener{	
	@Override
	public void onEvent(Event e) {
		e.print();
	}
}

//事件源
public class EventResource {

	private List listenerList = new ArrayList<>();
	
	private Event e = new Event();
	
	public void register(Listener listener) {
		this.listenerList.add(listener);
	}
	
	public void operte() {
		System.out.println("EventResource.operte***************");
		this.listenerList.forEach(listener -> listener.onEvent(e));
	}
	
	public static void main(String[] args) {
		EventResource eventResource = new EventResource();
		eventResource.register(new ListenerImpl());
		eventResource.operte();
	}
	
}

10.命令模式

应用场景:应用不是太广泛,举个例子说明一下,activiti对数据库的各种操作就使用了命令模式,activiti把对数据库的操作都封装在各个不同的命令中,调用方即命令下达者,操作数据库的API即执行者,相互之间依赖接口是解耦的。

这里需要注意三个对象,命令下达者(持有命令对象),命令(持有至少一个命令执行者对象和命令内容),命令执行者(执行命令)

//命令下达规范
public interface ILeader {
	//下达命令
	void command();
}

//命令下达者的一个实现
public class LeaderImplOne implements ILeader{

	//持有命令对象
	private ICommand command;

	//构造注入一个命令
	public LeaderImplOne(ICommand command){
		this.command = command;
	}
	
	//下达命令
	public void command() {
		command.transferCommand();
	}

}

//命令下达者实现...N

//命令规范
public interface ICommand {
	//传递命令
	void transferCommand();
}

//命令实现1
public class CommandImplOne implements ICommand{
	
	//持有若干执行者的对象
	private IExecutor[] executors;
	
	//持有某个执行者的对象
	private IExecutor executor;
	
	//持有命令内容
	private String content;
	
	//构建一个命令对象,需要接收一个或多个执行者,和命令内容
	public CommandImplOne (IExecutor[] executors,String content){
		this.executors = executors;
		this.content = content;
	}
	
	//构建一个命令对象,需要接收一个或多个执行者,和命令内容
	public CommandImplOne (IExecutor executor,String content){
		this.executor = executor;
		this.content = content;
	}

	//传递命令给执行者去执行命令
	public void transferCommand() {
		if(executors != null && executors.length > 0){
			for(int i = 0; i < executors.length; i++){
				executors[i].execute(content);
			}
		}		
		
		if(executor != null){
			executor.execute(content);
		}
		
	}
	
}

//命令实现2
public class CommandImplTwo implements ICommand{
	
	//持有若干执行者的对象
	private IExecutor[] executors;
	
	//持有某个执行者的对象
	private IExecutor executor;
	
	//持有命令内容
	private Map content;
	
	//构建一个命令对象,需要接收一个或多个执行者,和命令内容
	public CommandImplTwo (IExecutor[] executors,Map content){
		this.executors = executors;
		this.content = content;
	}
	
	//构建一个命令对象,需要接收一个或多个执行者,和命令内容
	public CommandImplTwo (IExecutor executor,Map content){
		this.executor = executor;
		this.content = content;
	}

	//传递命令给执行者去执行命令
	public void transferCommand() {
		if(executors != null && executors.length > 0){
			for(int i = 0; i < executors.length; i++){
				executors[i].execute(content);
			}
		}
		
		if(executor != null){
			executor.execute(content);
		}
		
	}
	
}

//命令实现...N

//命令执行者规范
public interface IExecutor {
	//执行命令
	void execute(String content);
	
	//执行命令
	void execute(Map content);
}

//命令执行者实现1
public class ExecutorImplOne implements IExecutor {


	public void execute(String content) {
		//模拟执行者执行命令逻辑
		System.out.println("命令执行1执行了命令,打印 content:" + content);
	}

	public void execute(Map content) {		
		//模拟执行者执行命令逻辑
		System.out.println("命令执行1执行了命令,打印 content.size:" + content.size());
	}

}

//命令执行者实现2
public class ExecutorImpTwo implements IExecutor {


	public void execute(String content) {
		//模拟执行者执行命令逻辑
		System.out.println("命令执行者2执行了命令,打印 content:" + content);
	}

	public void execute(Map content) {		
		//模拟执行者执行命令逻辑
		System.out.println("命令执行者2执行了命令,打印 content.size:" + content.size());
	}

}

//命令执行者实现...N

//测试命令模式
public static void testCommand(){
	//构建多个命令执行者的数组对象
	IExecutor[] executors = {new ExecutorImplOne(),new ExecutorImpTwo()};

	//构建命令对象,并传入多个执行者的数组对象,命令内容		
	CommandImplOne commandOne = new CommandImplOne(executors,"命令1");
	
	//构建命令下达者,下达命令
	new LeaderImplOne(commandOne).command();
}

11.责任链模式

应用场景:责任链应用还是相当广泛的,例如springmvc的处理器链就使用了该设计模式,其原理是,前台发送一个请求,会被处理器链中的各种拦截器进行拦截,分别进行各自的处理。总之,如果你有一个对象需要同时被其他多个对象分别进行不同的处理,并且这个过程是线性的,即同步执行的,那么我们可以考虑使用责任链模式。这么做的好处是,被处理对象和各个处理对象进行解耦,进行自由组装。

//首先定义一个处理器模板
public abstract class Handler {

	//下一任处理器
	protected Handler nextHandler;
	
	//上一任处理器
	protected Handler lastHandler;
	
	//当前处理器名称
	protected String handlerName;
	
	//构造注入处理器名称
	public Handler (String handlerName){
		this.handlerName = handlerName;
	}
	
	//注入下一步处理器,同时把当前处理器赋值给下一任处理器的前任
	public void setNextHandler(Handler nextHandler){
		this.nextHandler = nextHandler;
		nextHandler.lastHandler = this; 
	}

	//模板处理方法,接收一个Request参数
	public abstract void handle(Request request);

}

//自定义一个请求
public class Request {
	
	//持有一个map作为属性栈
	private Map attributes;

	//构造时不注入,则new一个attributes
	public Request(){
		attributes = new HashMap<>();
	}
	
	//构造时注入一个attributes
	public Request(Map attributes){
		this.attributes = attributes;
	}

	//attributes的set、get方法
	public Map getAttributes() {
		return attributes;
	}
	public void setAttributes(Map attributes) {
		this.attributes = attributes;
	}
	
	//向attributes中添加属性
	public void setAttribute(String key,Object value){
		attributes.put(key, value);
	}
	
	//根据key从attributes中获取属性
	public Object getAttribute(String key){
		return attributes.get(key);
	}
	
}

//处理器的一个实现HandlerImplA
public class HandlerImplA extends Handler {

	public HandlerImplA(String handlerName) {
		super(handlerName);
	}

	@Override
	public void handle(Request request) {
		System.out.println("HandlerImplA打印当前request中的属性数量:" + request.getAttributes().size());
		request.setAttribute(this.handlerName + ".attr", this.handlerName + ".val");	
		nextHandler.handle(request);
	}

}

//处理器的一个实现HandlerImplB
public class HandlerImplB extends Handler {

	public HandlerImplB(String handlerName) {
		super(handlerName);
	}

	@Override
	public void handle(Request request) {
		System.out.println("HandlerImplB打印它的上一任处理名称:" + lastHandler.handlerName);
		nextHandler.handle(request);
	}

}

//最终处理请求的实现ActualHandler
public class ActualHandler extends Handler {

	public ActualHandler(String handlerName) {
		super(handlerName);
	}

	@Override
	public void handle(Request request) {
		System.out.println("ActualHandler打印request中的所有参数如下:");
		Map attributes = request.getAttributes();
		Set> entrySet = attributes.entrySet();
		for (Entry entry : entrySet) {
			System.out.println("request.attrName:" + entry.getKey() + " request.attrVal:" + entry.getValue());
		}
	}

}

//测试责任链模式
public static void testResponsibility(){
	//构建请求
	Request request = new Request();
	ActualHandler handler = new ActualHandler("handler");
	HandlerImplB handlerB = new HandlerImplB("handlerB");
	handlerB.setNextHandler(handler);
	HandlerImplA handlerA = new HandlerImplA("handlerA");
	handlerA.setNextHandler(handlerB);
	//从A开始处理
	handlerA.handle(request);
}

控制台打印如下:

HandlerImplA打印当前request中的属性数量:0
HandlerImplB打印它的上一任处理名称:handlerA
ActualHandler打印request中的所有参数如下:
request.attrName:handlerA.attr request.attrVal:handlerA.val


12.状态模式

应用场景:逻辑上超过 3 层的 if-else 代码可以使用卫语句,或者状态模式来实现。这句话是阿里的java开发手册中的规范,很明显,状态模式的设计就是为了替换if-else的。那么为什么要用状态模式替换if-else呢?这才是用状态模式的原因,网上大多数人云亦云的解释都说是为了便于维护和扩展,我却没觉得用了状态模式怎么就能不修改原代码的情况下进行扩展,但是还是来学习一下吧,因为确实是便于维护了

//定义一个持有状态的事物
public class ThingObject {
	
	//持有状态
	private StateTemplate state;

	//构造把状态置为null
	public ThingObject() {
		this.state = null;
	}
	
	//获取当前的状态
	public StateTemplate getState() {
		return state;
	}

	//改变当前状态,并改变对应状态的行为
	public boolean setState(StateTemplate state) {
		this.state = state;
		return state.doAction();				
	}
	
	//没有对应的状态情的况下的行为
	public static void doAction(){
		//执行没有对应状态的逻辑
		System.out.println("没有对应状态执行的逻辑");
	}
	
}

//定义一个状态模板
public abstract class StateTemplate {
	
	//状态参数
	protected int states;
	
	//构造注入状态参数
	public StateTemplate(int states){
		this.states = states;
	}

	//抽象行为
	public abstract boolean doAction();
	
}

//定义一个关于状态参数states的枚举
public enum StatesEnum {
	
	STATE1(1),STATE2(2),STATE3(3),STATE4(4),STATE5(5),STATE6(6),STATE7(7),STATE8(8);
	
	public Integer value;
	
	private StatesEnum(Integer value){
		this.value = value;
	}
	
}

//状态1实现
public class StateOne extends StateTemplate {
	
	//构造注入状态参数并交由父类
	public StateOne(int states) {
		super(states);
	}

	@Override
	public boolean doAction() {

		//如果当前状态参数是1就执行该行为,否则什么也不做
		if(super.states == StatesEnum.STATE1.value){
			System.out.println("状态111执行的逻辑");
			return true;
		}
		return false;
	}

}

//状态2实现
public class StateTwo extends StateTemplate {

	public StateTwo(int states) {
		super(states);
	}

	@Override
	public boolean doAction() {
		if(super.states == StatesEnum.STATE2.value){
			//状态2对应的行为
			System.out.println("状态222执行的逻辑");
			return true;
		}
		return false;
	}

}

//状态3实现
public class StateThree extends StateTemplate {

	public StateThree(int states) {
		super(states);
	}

	@Override
	public boolean doAction() {
		if(super.states == StatesEnum.STATE3.value){
			//状态2对应的行为
			System.out.println("状态333执行的逻辑");
			return true;
		}
		return false;
	}

}

//状态N...实现

//测试状态模式
public static void testState(int states){		
	
	ThingObject t = new ThingObject();
	if(t.setState(new StateOne(states))) return;
	if(t.setState(new StateTwo(states))) return;	
	if(t.setState(new StateThree(states))) return;
	
	//执行没有对应状态的逻辑
	ThingObject.doAction();
	
}

       上述测试代码的if return可以去掉的,只是为了完全真实模拟if-else的效果才加的,如果现在我需要扩展一个条件4的情况,那么只需加一个状态模板的实现StateFour,然后再测试代码的倒数第二行在加一句if(t.setState(new StateFour(states))) return;即可,很明显客户端还是要修改源码,并没有真正的实现开闭原则。

13.访问者模式

应用场景:把对源对象的各种不同操作,抽象出来成为一个规范,然后实现该规范的各个实现类即是访问者对象,访问者持有源对象,因此可以操作源对象的数据结构。这种时候就可以使用该模式,例如开发一个模块的多张报表的时候,可以使用这种模式,如果需要新增报表,只需添加访问者即可

//被访问者对象
public class BeVisitor {

    //接受一个访问
	public void accept(IVisitor visitor) {
		visitor.visite(this);
	}

	private Integer attr1;
	private String attr2;
	private boolean attr3;

	public Integer getAttr1() {
		return attr1;
	}

	public void setAttr1(Integer attr1) {
		this.attr1 = attr1;
	}

	public String getAttr2() {
		return attr2;
	}

	public void setAttr2(String attr2) {
		this.attr2 = attr2;
	}

	public boolean isAttr3() {
		return attr3;
	}

	public void setAttr3(boolean attr3) {
		this.attr3 = attr3;
	}

}

//访问者规范
public interface IVisitor {
	void visite(BeVisitor beVisitor);
}

//访问者1
public class VisitorOne implements IVisitor {

	public void visite(BeVisitor beVisitor) {
		System.out.println("------------VisitorOne print:------------");
		System.out.println(beVisitor.getAttr1() + "---" + beVisitor.getAttr2());
	}

}

//访问者2
public class VisitorTwo implements IVisitor {

	public void visite(BeVisitor beVisitor) {
		System.out.println("------------VisitorTwo print:------------");
		if(beVisitor.isAttr3()){
			System.out.println(beVisitor.getAttr1() + "---" + beVisitor.getAttr2());
		}else{
			System.out.println("beVisitor.isAttr3(): " + false);
		}
	}

}

//测试访问者模式
public static void testVisitor(){
	BeVisitor beVisitor = new BeVisitor();
	beVisitor.setAttr1(20);
	beVisitor.setAttr2("张三");
	beVisitor.setAttr3(false);
    //接受访问者1的访问
	beVisitor.accept(new VisitorOne());
    //接受访问者2的访问
	beVisitor.accept(new VisitorTwo());
}

14.模板方法

应用场景:如果需要分别实现规范中的方法,可以使用这种模式

//规范
public interface IPhone {
	
	public void call();
	
	public void photograph();
	
	public void music();
	
	public void sendMsg();
}

//模板方法类
public abstract class PhoneTemplate implements IPhone {

	@Override
	public void call() {
		System.out.println("call()*********");
	}

	@Override
	public void sendMsg() {
		System.out.println("sendMsg()********");
	}

}

//实现Vivo
public class Vivo extends PhoneTemplate {

	@Override
	public void photograph() {
		System.out.println("vivo -> photograph()********");
	}

	@Override
	public void music() {
		System.out.println("vivo -> music()********");
	}
	
}

//实现XiaoMi
public class XiaoMi extends PhoneTemplate {

	@Override
	public void photograph() {
		System.out.println("XiaoMi -> photograph()********");
	}

	@Override
	public void music() {
		System.out.println("XiaoMi -> music()********");
	}

}

//测试
public static void main(String[] args) {
	XiaoMi xiaoMi = new XiaoMi();
	xiaoMi.call();
	xiaoMi.sendMsg();
	xiaoMi.music();
}

15.策略模式

使用场景非常广泛,一个行为有不同的表现形式的时候,可以使用策略模式。

策略模式与桥接模式在代码层面没有本质区别,只是设计的出发点不同。

例如:四则运算法则,定义一个运算行为(策略),有加减乘除四则运算形式(策略实现),策略持有(策略使用者)

//计算策略
public interface StrategyCalculate {

	public double calculate(double a, double b);
	
}

//默认策略实现
public class DefaultStrategyCalculate implements StrategyCalculate {

	@Override
	public double calculate(double a, double b) {
		return a + b;
	}

}

//另一个策略实现
public class SubtractionStrategyCalculate implements StrategyCalculate {

	@Override
	public double calculate(double a, double b) {
		return a - b;
	}

}

//策略使用者
public class StrategyCalculateHolder {
	
	private StrategyCalculate strategyCalculate;
	
	public StrategyCalculateHolder(StrategyCalculate strategyCalculate) {
		this.strategyCalculate = strategyCalculate;
	}
	
	public double calculate(double a, double b) {
		return this.strategyCalculate.calculate(a, b);
	}
	
	public static void main(String[] args) {
		System.out.println(new StrategyCalculateHolder(new DefaultStrategyCalculate()).calculate(20, 10));
		System.out.println(new StrategyCalculateHolder(new SubtractionStrategyCalculate()).calculate(20, 10));
	}
	
}

 

你可能感兴趣的:(java常用设计模式学习总结)