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 IO
String 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