创建型:单例模式,工厂方法模式等等
结构型:静态代理模式,动态代理模式,装饰者模式,适配器模式,桥接模式
行为型:观察者模式,命令模式,责任链模式,状态模式,访问者模式
应用场景:顾名思义,自始至终都操作的是同一个对象的时候,需要用单例模式
/**
* 单例懒汉式(比较常用)
*/
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();
}
}
}
应用场景:
当我们需要获取同一规范下的各个不同实现的对象,并且再获取这些对象的时候比较麻烦的情况下,可以考虑使用工厂模式。
在扩展规范的实现的时候,同时又需要去扩展工厂,为了便于扩展,适应于开闭原则,因此产生了工厂方法模式,即一个工厂只创建规范下的一个实现的对象。
不同的对象的创建对应不同的工厂,那么这些不同的工厂就可以抽象出一个模板出来,或者提前定义一个接口出来。
/*
* 需要被使用工厂创建的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 extends PersonFactory> 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();
}
}
}
应用场景:用的不太多,一般用动态代理
//被代理的规范
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();
}
应用场景: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:
//被代理类
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();
}
应用场景:当我们需要动态的横向扩展程序的时候,即动态的扩展某一对象的方法,可以用装饰者模式
注意与动态代理的区别:
动态代理是对任意对象的方法扩展,但扩展的内容是固定不变的
装饰者模式是对某一个对象的方法扩展,扩展的内容是可以动态变化的
//被装饰的规范
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();
}
应用场景:比如应用中有一个类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();
}
}
应用场景:当我们需要操作规范,但又无法固定实现的时候,可以提供一组规范,让客户方来实现,我们操作的时候只需注入客户方的实现对象,这种模式就是桥接模式,例如: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");
}
应用场景:观察者模式略微难理解,但十分重要,例如监听器就需要使用观察者模式来实现
//定义观察者规范
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();
}
//事件
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();
}
}
应用场景:应用不是太广泛,举个例子说明一下,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();
}
应用场景:责任链应用还是相当广泛的,例如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);
}
控制台打印如下:
应用场景:逻辑上超过 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;即可,很明显客户端还是要修改源码,并没有真正的实现开闭原则。
应用场景:把对源对象的各种不同操作,抽象出来成为一个规范,然后实现该规范的各个实现类即是访问者对象,访问者持有源对象,因此可以操作源对象的数据结构。这种时候就可以使用该模式,例如开发一个模块的多张报表的时候,可以使用这种模式,如果需要新增报表,只需添加访问者即可
//被访问者对象
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());
}
应用场景:如果需要分别实现规范中的方法,可以使用这种模式
//规范
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();
}
使用场景非常广泛,一个行为有不同的表现形式的时候,可以使用策略模式。
策略模式与桥接模式在代码层面没有本质区别,只是设计的出发点不同。
例如:四则运算法则,定义一个运算行为(策略),有加减乘除四则运算形式(策略实现),策略持有(策略使用者)
//计算策略
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));
}
}