1、结构器模式
对于结构器模式,是如果有一个对象波及到多个参数须要设置的时候,能够应用结构器模式来构建外面的元素
比方有三个对象:
参考dolpinscheduler中的概念
流程定义
流程实例
工作实例
当初的需要是将三者封装成一个工作从Master传递到Worker,此时就能够应用结构器模式
比方构建一个TaskContext,其中蕴含了以上对象中的元素
而后应用一个构建一个TaskRequest应用结构器模式来构建对象
public class TaskRequest { private TaskContext taskContext = new TaskContext(); /** * 构建TaskRequest * @return */ public static TaskRequest newBuilder() { return new TaskRequest(); } /** * 设置工作相干信息 * @param task * @return */ public TaskRequest setTask(Task task) { taskContext.setTaskName(task.getTaskName()); taskContext.setTaskType(task.getTaskType()); return this; } /** * 设置流程实例相干信息 * @param processInstance * @return */ public TaskRequest setProcessInstance(ProcessInstance processInstance) { taskContext.setExecuteUser(processInstance.getExecuteUser()); taskContext.setStartTime(processInstance.getStartTime()); taskContext.setEndTime(processInstance.getEndTime()); return this; } /** * 设置流程定义相干信息 * @param processDefinition * @return */ public TaskRequest setProcessDefinition(ProcessDefinition processDefinition) { taskContext.setProjectName(processDefinition.getProjectName()); return this; } /** * 获取工作上下文 * @return */ public TaskContext build() { return taskContext; }}
2、组合模式 + 访问者模式
对于树形构造的id,pid模式的就能够应用组合模式 + 访问者模式
/** * 组合模式 + 访问者模式 */public class CompositeDemo { public static void main(String[] args) { Priority root = new Priority(); root.setName("易观"); Priority dept1 = new Priority(); dept1.setName("大数据平台"); Priority dept2 = new Priority(); dept2.setName("数据平台"); List<Priority> children = new ArrayList<>(); children.add(dept1); children.add(dept2); root.setChildren(children); RelatedCheckPriority relatedCheckPriority = new RelatedCheckPriority(); root.execute(relatedCheckPriority); Boolean relateCheckResult = relatedCheckPriority.getRelateCheckResult(); // 如果都有权限,再删除 if (relateCheckResult){ RemovePriority removePriority = new RemovePriority(); root.execute(removePriority); } }}class Priority { private String name; private List<Priority> children = new ArrayList<>(); public void execute(PriorityOperation operation){ operation.doExecute(this); }}interface PriorityOperation { void doExecute(Priority priority);}class RemovePriority implements PriorityOperation{ @Override public void doExecute(Priority priority) { List<Priority> childrenList = priority.getChildren(); if (childrenList != null && childrenList.size() > 0){ for (Priority child : childrenList){ child.execute(this); } } System.out.println("删除 : " + priority.getName()); }}class RelatedCheckPriority implements PriorityOperation { /** * 关联查看后果 */ private Boolean relateCheckResult = false; @Override public void doExecute(Priority priority) { List<Priority> childrenList = priority.getChildren(); if (childrenList != null && childrenList.size() > 0){ for (Priority child : childrenList){ child.execute(this); } } // 这里须要对node进行业务判断,是否有权限 relateCheckResult = true; } public Boolean getRelateCheckResult() { return relateCheckResult; } public void setRelateCheckResult(Boolean relateCheckResult) { this.relateCheckResult = relateCheckResult; }}
3、单例
class Singleton { /** * 应用volatile防止指令重排 */ private static volatile Singleton instance = null; /** * 构造方法私有化 */ private Singleton(){} /** * 获取实例 * @return */ public static Singleton getInstance(){ // 比如说我线程1到这里了,而后线程1,返回的instance就会有问题 if (instance == null){ synchronized (Singleton.class){ if (instance == null){ instance = new Singleton(); /** * 线程2执行到这里了,因为instance的指令重排 * 导致instance援用不为null,然而外面的成员是null */ } } } return instance; }}
4、状态模式
在简单状态变换的时候,应用状态模式,状态机,从一个状态到另外一个状态转换
public class Task { private String taskName; private String taskType; private String state;}public interface TaskState { /** * 状态转换 * @param task */ void doTransform(Task task); /** * 判断以后状态下是否能够kill * @param task * @return */ Boolean canKill(Task task); /** * 判断以后状态下是否能够删除工作 * @param task * @return */ Boolean canRemove(Task task);}public class RunningTaskState implements TaskState { @Override public void doTransform(Task task) { System.out.println(task.getTaskName() + "由提交胜利态到正在运行状态"); } @Override public Boolean canKill(Task task) { return false; } @Override public Boolean canRemove(Task task) { return true; }}public class FinishedTaskState implements TaskState { @Override public void doTransform(Task task) { System.out.println(task.getTaskName() + "由正在运行状态到完结状态"); } @Override public Boolean canKill(Task task) { return true; } @Override public Boolean canRemove(Task task) { return false; }}public class StateManager { public static final String SUBMITED = "submited"; public static final String RUNNING = "running";public static final String FINISHED = "finished"; private RunningTaskState runningTaskState; private FinishedTaskState finishedTaskState; public StateManager(RunningTaskState runningTaskState,FinishedTaskState finishedTaskState) { this.runningTaskState = runningTaskState; this.finishedTaskState = finishedTaskState; } public void runTask(Task task) { runningTaskState.doTransform(task); } public void completeTask(Task task) { finishedTaskState.doTransform(task); } public Boolean canKill(Task task) { return getTaskState(task).canKill(task); } public Boolean canRemove(Task task) { return getTaskState(task).canRemove(task); } private TaskState getTaskState(Task task) { if (SUBMITED.equals(task.getState())) { return runningTaskState; } else if (RUNNING.equals(task.getState())) { return finishedTaskState; } return null; }}public class StateDemo { public static void main(String[] args) { StateManager stateManager = new StateManager( new RunningTaskState(), new FinishedTaskState() ); Task task = new Task(); task.setTaskName("测试工作"); task.setTaskType("SHELL"); task.setState(StateManager.SUBMITED); stateManager.runTask(task); System.out.println(stateManager.canKill(task)); System.out.println(stateManager.canRemove(task)); }}
5、策略模式
依据不同的策略抉择进去指标的ip
public class StrategyDemo { public static void main(String[] args) { Strategy strategy = new Strategy(); RandomSelector randomSelector = new RandomSelector(); RoundRobinSelector roundRobinSelector = new RoundRobinSelector(); String host1 = strategy.select("xx1,xx2", randomSelector); String host2 = strategy.select("xx1,xx2", roundRobinSelector); System.out.println(host1); System.out.println(host2); }}class Strategy { public String select(String hosts, Selector selector) { String host = selector.select(hosts); return host; }}interface Selector { String select(String hosts);}/*** 随机抉择*/class RandomSelector implements Selector{ @Override public String select(String hosts) { return "127.0.0.1"; }}/*** 轮询抉择*/class RoundRobinSelector implements Selector { @Override public String select(String hosts) { return "127.0.0.2"; }}
6、模板办法
public class TemplateMethodDemo { public static void main(String[] args) { HttpServlet httpServlet = new MyHttpServlet(); httpServlet.doService("get"); }}abstract class HttpServlet { public void doService(String type){ // 公共的业务逻辑 if ("get".equals(type)) { doGet(); } else if ("post".equals(type)) { doPost(); } } protected void doGet() {} protected void doPost() {}}class MyHttpServlet extends HttpServlet{ @Override protected void doGet() { System.out.println("发送get申请"); }}
7、迭代器模式
public class IteratorDemo { public static void main(String[] args) { DBManager dbManager = new DBManagerImpl(); DBIterator iterator = dbManager.iterator(); while (iterator.hasNext()){ List<String> result = iterator.next(); System.out.println(result); } }}interface DBManager { DBIterator iterator();}class DBManagerImpl implements DBManager { @Override public DBIterator iterator() { return new DBIteratorImpl(); }}interface DBIterator { Boolean hasNext(); List<String> next();}class DBIteratorImpl implements DBIterator { LinkedList<String> list = new LinkedList<>(); public DBIteratorImpl(){ list.offer("数据1"); list.offer("数据2"); list.offer("数据3"); list.offer("数据4"); } @Override public Boolean hasNext() { return !list.isEmpty(); } @Override public List<String> next() { ArrayList<String> dest = new ArrayList<>(); dest.add(list.poll()); dest.add(list.poll()); return dest; }}
8、备忘录模式
这个针对的是DS的TaskPriorityQueueImpl 和 TaskPriorityQueueConsumer
public void put(StockUpdateMessage message) throws Exception { /** * 每次要往内存队列放音讯之前,先检查一下离线存储标识 * 如果触发了离线存储,间接就往离线存储中写入,不要走前面的逻辑了 * 写完离线存储之后,须要检查一下内存队列的大小,如果内存队列曾经清零,则启动一个后盾线程 * 让后盾线程去将离线存储中的数据恢复写入内存队列中 */ if (offlineStorageManager.getOffline()){ //往DB中放数据 offlineStorageManager.store(message); if (queue.size() == 0){ new OfflineResumeThread(offlineStorageManager,this).start(); } return; } // 如果内存队列曾经满了,此时就触发离线存储 if (QUEUE_MAX_SIZE.equals(queue.size())){ offlineStorageManager.store(message); offlineStorageManager.setOffline(true); return; } queue.put(message);}OfflineResumeThread 线程:public void run() { try { OfflineStorageIterator iterator = offlineStorageManager.iteartor(); // 如果表中还有数据的话 while (iterator.hasNext()){ try { // 每次就从mysql中查问50条数据,批量查问,批量解决,批量删除 List<StockUpdateMessage> stockUpdateMessages = iterator.next(); // 将这批数据写入内存队列中 for (StockUpdateMessage message : stockUpdateMessages){ stockUpdateQueue.putDirect(message); } // 批量删除这批数据 offlineStorageManager.removeByBatch(stockUpdateMessages); }catch (Exception e){ logger.error("error",e); } } // 此时mysql中的数据全副复原,更新内存标识 offlineStorageManager.setOffline(false); }catch (Exception e){ logger.error("error",e); } }
9、责任链模式
public class ChainPatternDemo { public static void main(String[] args) { HandlerFactory factory = new HandlerFactory(); Handler handlerChain = factory.getHandlerChain(); handlerChain.execute(); }}class HandlerFactory { Handler firstHandler; public Handler getHandlerChain(){ buildHandlerChain(); return firstHandler; } private void buildHandlerChain(){ Handler thirdHandler = new ProcessResult(null); Handler secondHandler = new ExecuteTask(thirdHandler); firstHandler = new ResolveParamter(secondHandler); }}abstract class Handler { protected Handler successor; public Handler(Handler successor){ this.successor = successor; } abstract void execute();}class ResolveParamter extends Handler { public ResolveParamter(Handler successor) { super(successor); } @Override void execute() { System.out.println("解析参数"); if (successor != null){ successor.execute(); } }}class ExecuteTask extends Handler { public ExecuteTask(Handler successor) { super(successor); } @Override void execute() { System.out.println("执行工作"); if (successor != null){ successor.execute(); } }}class ProcessResult extends Handler { public ProcessResult(Handler successor) { super(successor); } @Override void execute() { System.out.println("处理结果"); if (successor != null){ successor.execute(); } }}
10、门面模式
Service就是经典的门面模式,交融了很多dao
public class FacadePatternDemo { public static void main(String[] args) { /** * 假如是子系统2 */ SystemFacade facade = new SystemFacade(); facade.execute(); /** * 益处1:子系统2不须要care太多的模块,只有care一个门面类的接口就能够了 * 益处2:如果多个中央都要调用这段逻辑,那么如果这个逻辑变了,只须要在门面类一个中央批改就能够了 */ } /** * 子系统1的门面类 */ public static class SystemFacade { public void execute(){ /** * 子系统,封装了本人的多个模块,ABC,基于本人多个模块的性能,对外对立裸露进来一个性能 */ ModuleA moduleA = new ModuleA(); ModuleB moduleB = new ModuleB(); ModuleC moduleC = new ModuleC(); moduleA.execute(); moduleB.execute(); moduleC.execute(); System.out.println("新增的一段逻辑"); } } public static class ModuleA { public void execute() { System.out.println("子系统1的模块A的性能"); } } public static class ModuleB { public void execute() { System.out.println("子系统1的模块B的性能"); } } public static class ModuleC { public void execute() { System.out.println("子系统1的模块C的性能"); } }}
11、装璜模式
对办法的加强
public class DecoratorPatternDemo { public static void main(String[] args) { ConcreteComponent concreteComponent = new ConcreteComponent(); Decorator decorator = new Decorator(concreteComponent); decorator.execute(); }}interface Component { void execute();}class ConcreteComponent implements Component { @Override public void execute() { System.out.println("执行根底性能"); }}class Decorator implements Component { private Component component; public Decorator(Component component){ this.component = component; } @Override public void execute() { System.out.println("在执行根底性能之前,执行局部性能加强"); component.execute(); System.out.println("在执行根底性能之后,执行局部性能加强"); }}
12、适配器
public class AdapterPatterDemo { public static void main(String[] args) { NewInterface oldObject = new NewInterfaceAdapter(new OldInterfaceImpl()); oldObject.newExecute(); NewInterface newOjbect = new NewInterfaceImpl(); newOjbect.newExecute(); /** * 适配器 * 就是你手上有新老两个接口和一个老接口的实现类 * 然而当初零碎中药面向新接口来开发,老接口的实现类就不能间接用了,不能间接面向老接口来开发 * 开发一个老接口到新接口的一个适配器 * 适配器是实现了新接口的,然而适配器中持有老接口实现类实例的援用 * 适配器的新接口办法的实现,全副基于老接口实现类的老办法来实现即可 * 对于调用方而言,只有应用适配器开发即可,就能够通过面向新接口开发,底层应用老接口实现类 */ } /** * 定义一个适配器 */ public static class NewInterfaceAdapter implements NewInterface{ private OldInterface oldObject; public NewInterfaceAdapter(OldInterface oldObject){ this.oldObject = oldObject; } @Override public void newExecute() { oldObject.oldExecute(); } } /** * 老版本接口 */ public static interface OldInterface{ void oldExecute(); } public static class OldInterfaceImpl implements OldInterface{ @Override public void oldExecute() { System.out.println("老版本接口实现的性能逻辑"); } } /** * 新版版接口 */ public static interface NewInterface{ void newExecute(); } public static class NewInterfaceImpl implements NewInterface{ @Override public void newExecute() { System.out.println("新版本接口实现的性能逻辑"); } }}
Java IOString SEPARATOR = File.separator; File file = new File("e:" + SEPARATOR + "io" + SEPARATOR + "test.txt"); //BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); // 备注下面这个初始化过程就是屡次应用包装来实现的,不举荐这么写,会让老手看不懂。 //1、取得子节输出流 FileInputStream fileInputStream=new FileInputStream(file); //2、结构转换流(是继承Reader的) InputStreamReader inputStreamReader=new InputStreamReader(fileInputStream); //3、 结构缓冲字符流 BufferedReader bufferedReader=new BufferedReader(inputStreamReader); /** * 备注1、2两步骤体现出了适配器模式 * 因为InputStream是字节流不能享受到字符流读取字符那么便捷的性能,因而借助 * InputStreamReader将其转为Reader子类,因而能够领有便捷操作文本文件办法。 */ /** * 2、3两步骤体现了装璜模式(wrapper包装模式) * 将InputStream字节流包装为BufferedReader过程就装璜的过程。一开始 * InputStream只有read一个字节的办法,包装为Reader之后领有read一个字符的功 * 能,在包装成BufferedReader之后就领有read一行字符串性能 */
13、原型模式
public <T> T clone(Class<T> clazz) throws Exception{ T target = clazz.newInstance(); BeanCopierUtils.copyProperties(this,target); return target;}
BeanCopierUtils 是cglib的一个工具对于类之间的clone
14、享元模式
比如说Worker将返回值返回给Master之后,Master应用Map进行保留,而后对于Master基于工作的状态的判断,走的是这个Map,如果缓存中有则走缓存,没有则走数据库
15、代理模式
JDK
public class JDKProxyDemo { public static void main(String[] args) throws Exception { JDKProxy proxy = new JDKProxy(); IUserManager userManager = (IUserManager)proxy.bind(new UserManagerImpl()); userManager.addUser("zhagnsan","123"); }}interface IUserManager { void addUser(String id, String password);}class UserManagerImpl implements IUserManager { @Override public void addUser(String id, String password) { System.out.println("======调用了UserManagerImpl.addUser()办法======"); }}class JDKProxy implements InvocationHandler { private Object target; public Object bind(Object target){ this.target = target; return Proxy.newProxyInstance(this.target.getClass().getClassLoader(), this.target.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(this.target,args); return result; }}CGLIB/** * CGLibProxy动静代理类 */public class CGLibProxy implements MethodInterceptor { /** CGLib须要代理的指标对象 */ private Object targetObject; public Object createProxyObject(Object obj) { this.targetObject = obj; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(obj.getClass()); enhancer.setCallback(this); Object proxyObj = enhancer.create(); // 返回代理对象 return proxyObj; } @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Object obj = method.invoke(targetObject, args); return obj; }}
Dubbo客户端动静代理
public class NettyClient { private static ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); private static NettyClientHandler clientHandler; //TODO 在这里实现了动静代理模式 public Object getBean(final Class<?> serviceClass,final String provideName) { return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class<?>[]{serviceClass},(proxy, method, args) -> { if (clientHandler == null) { //TODO 在这里初始化netty客户度,初始化的时候曾经和server建设的连贯,有了上下文 initClient(); } //TODO 初始化结束之后给客户度设置参数,HelloService#hello#你好 clientHandler.setParam(provideName + args[0]); //TODO 通过线程池对工作进行提交,因为NettyClientHandler实现了Callable接口,所以能够间接进行工作的提交 return executorService.submit(clientHandler).get(); }); } private static void initClient() { clientHandler = new NettyClientHandler(); EventLoopGroup group = new NioEventLoopGroup(); Bootstrap bootstrap = new Bootstrap(); bootstrap.group(group) .channel(NioSocketChannel.class) .option(ChannelOption.TCP_NODELAY,true) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(clientHandler); } }); try { bootstrap.connect("127.0.0.1",7777).sync(); } catch (Exception e) { e.printStackTrace(); } }}public class NettyClientHandler extends ChannelInboundHandlerAdapter implements Callable { private ChannelHandlerContext context; private String result; private String param; @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { context = ctx; } @Override public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { //TODO 在这里期待后果返回 result = msg.toString(); notify(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { } @Override public synchronized Object call() throws Exception { //TODO 这里将数据写了进来 context.writeAndFlush(param); wait(); return result; } void setParam(String param) { this.param = param; }}动静代理public class Demo { public static void main(String[] args) throws Exception { JdkHandler jdkHandler = new JdkHandler(); User bookApi = (User)jdkHandler.bind(User.class); bookApi.say("qiaozhanwei"); bookApi.say("qiaozhanwei",30); }}interface User { void say(String name); void say(String name,int age);}class JdkHandler implements InvocationHandler { public Object bind(Class<?> serviceClass) { return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class<?>[]{serviceClass},this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { for (Object object : args) { System.out.println(object); } System.out.println(method.getName()); return null; }}
总结
1)JDK动静代理只能对实现了接口的类生成代理,而不能针对类
2)CGLIB是针对类实现代理,次要是对指定的类生成一个子类,笼罩其中的办法,并笼罩其中办法实现加强,然而因为采纳的是继承,所以该类或办法最好不要申明成final