1

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

如感兴趣,点赞加关注,谢谢


journey
32 声望21 粉丝