Third, the Advanced Programmer - Design Patterns

Disclaimer: if not more, in essence https://blog.csdn.net/qq_29857681/article/details/90168976

Visitor Pattern

The essence of the: without changing the internal elements of the object based on the realization of different visitors have different operations.

Example: After the personnel designated price to get a prescription calculate the total price based on the drug name and number, and pharmacy staff preparing the drug according to the drug name and number

Here is the prescription of a single complex object, prescription items inside is the internal elements of the object

Staff and pharmacy personnel designated price are two different visitors.

 

Code:

package com.jd.testjava.testdesignpattern.visitor3;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

interface Element {
    void accept(IVisitor visitor);

    void doSomething();
}

class ConcreteElement1 implements Element {
    @Override
    public void doSomething() {
        System.out.println("这是元素1");
    }

    @Override
    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }
}

class ConcreteElement2 implements Element {
    @Override
    public void doSomething() {
        System.out.println("这是元素2");
    }

    @Override
    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }
}

class ConcreteElement3 implements Element {
    @Override
    public void doSomething() {
        System.out.println("这是元素3");
    }

    @Override
    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }
}

interface IVisitor {
    void visit(ConcreteElement1 el1);

    void visit(ConcreteElement2 el2);

    void visit(ConcreteElement3 el3);
}

class Visitor implements IVisitor {
    @Override
    public void visit(ConcreteElement1 el1) {
        el1.doSomething();
    }

    @Override
    public void visit(ConcreteElement2 el2) {
        el2.doSomething();
    }

    @Override
    public void visit(ConcreteElement3 el3) {
        el3.doSomething();
    }
}

class ObjectStruture {
    public static List<Element> getList() {
        List<Element> list = new ArrayList<Element>();
        Random ran = new Random();
        for (int i = 0; i < 10; i++) {
            int a = ran.nextInt(100);
            if (a > 50) {
                list.add(new ConcreteElement1());
            } else {
                list.add(new ConcreteElement3());
            }
        }
        return list;
    }
}

public class Client {
    public static void main(String[] args) {
        List<Element> list = ObjectStruture.getList();
        for (Element e : list) {
            e.accept(new Visitor());
        }
    }
}

Template mode

Essence: control the behavior of the parent class, subclass be achieved

Example: When playing the game, the entire flow of the game have been planned, all games are in accordance with this process, do anything specific this process be implemented by a variety of actual game

package com.jd.testjava.testdesignpattern;

/**
 * 模板模式
 * @author lichenyang8
 * @date 2019/5/15
 */
public class TestTemplatePattern {
    public static void main(String[] args) {

        Game game = new Cricket();
        game.play();
        System.out.println();
        game = new Football();
        game.play();
    }
}

abstract class Game {
    abstract void initialize();
    abstract void startPlay();
    abstract void endPlay();

    //模板方法 final不能改变
    public final void play(){

        //初始化游戏
        initialize();

        //开始游戏
        startPlay();

        //结束游戏
        endPlay();
    }
}
class Cricket extends Game {

    @Override
    void endPlay() {
        System.out.println("Cricket Game Finished!");
    }

    @Override
    void initialize() {
        System.out.println("Cricket Game Initialized! Start playing.");
    }

    @Override
    void startPlay() {
        System.out.println("Cricket Game Started. Enjoy the game!");
    }
}
class Football extends Game {

    @Override
    void endPlay() {
        System.out.println("Football Game Finished!");
    }

    @Override
    void initialize() {
        System.out.println("Football Game Initialized! Start playing.");
    }

    @Override
    void startPlay() {
        System.out.println("Football Game Started. Enjoy the game!");
    }
}

Strategy Mode

Essence: to avoid the complexity of using multiple conditions judgment

Example: a page to share to different channels (QQ micro letter, circle of friends) different in different channels of content, then you can use the Strategy pattern, the different channels designed with different strategies, different policies different template content, behavior with the change in policy object to change the context object.

package com.jd.testjava.testdesignpattern;

/**
 * @author lichenyang8
 * @date 2019/5/15
 */
public class TestStrategyPattern {
    public static void main(String[] args) throws Exception {
        ShareContext context = ShareContext
                .getShareTarget(1);
        System.out.println(ShareContext.getShareInfo(context));
    }
}

/**
 * 标题
 */
interface ShareTitle {
    String showTitle();
}
//这样在新增分享渠道时 不用修改代码 只需要配置即可
/*配置文件
share.wechat.title=这个APP竟然这么棒
share.wechat.content=还不快来加入我们旅游派对
share.wechat.link.android=https://www.666.com/salesman/shareRegister?android&userToken=
share.wechat.link.ios=https://www.666.com/salesman/shareRegister?ios&userToken=
share.wechat.image.url.android=android wechat img url
share.wechat.image.url.ios=ios wechat img url

1=com.nicky.facade.sharestrategy.targets.QQShare
*/

/**
 * 微信标题
 */
class WechatTitle implements ShareTitle {

    @Override
    public String showTitle() {
        return BundleUtil.getResult("share.wechat.title");
    }
}

class ShareContext {

    protected ShareTitle shareTitle;


    public static ShareContext getShareTarget(Integer type) {
        //从配置文件中加载
        String className = BundleUtil.getResult(type.toString());
        Class cls;
        try {
            cls = Class.forName(className);
            return (ShareContext) cls.newInstance();
        } catch (ReflectiveOperationException e) {
            e.printStackTrace();
        }
        return null;
    }

    public final String showTitle() {
        return shareTitle.showTitle();
    }

    /**
     * 传入不同的context类 可以得到不同的分享内容
     * @param context
     * @param platform
     * @param userToken
     * @return
     */
    public static ShareInfo getShareInfo(ShareContext context, String platform, String userToken) {
        ShareInfo info = new ShareInfo();
        info.setTitle(context.showTitle());
        return info;
    }
}

/**
 * 微信分享
 */
class WechatShare extends ShareContext {
    public WechatShare() {
        super.shareTitle = new WechatTitle();
    }
}

Observer Pattern

Essence: to establish a trigger mechanism, the party has changed, in many ways immediately know

A typical publish - subscribe model

Example: micro-channel public number, there will be concern after the article push

package com.jd.testjava.testdesignpattern;

import java.util.ArrayList;
import java.util.List;

/**
 * @author lichenyang8
 * @date 2019/5/16
 */
public class TestObserverPattern {
    public static void main(String[] args) {
        WechatServer server = new WechatServer();

        Observer userZhang = new User("ZhangSan");
        Observer userLi = new User("LiSi");
        Observer userWang = new User("WangWu");

        server.registerObserver(userZhang);
        server.registerObserver(userLi);
        server.registerObserver(userWang);
        server.setInfomation("PHP是世界上最好用的语言!");

        System.out.println("----------------------------------------------");
        server.removeObserver(userZhang);
        server.setInfomation("JAVA是世界上最好用的语言!");

    }
}

interface Observerable {

    public void registerObserver(Observer o);
    public void removeObserver(Observer o);
    public void notifyObserver();

}

interface Observer {
    public void update(String message);
}

class WechatServer implements Observerable {

    //注意到这个List集合的泛型参数为Observer接口,设计原则:面向接口编程而不是面向实现编程
    private List<Observer> list;
    private String message;

    public WechatServer() {
        list = new ArrayList<Observer>();
    }

    @Override
    public void registerObserver(Observer o) {

        list.add(o);
    }

    @Override
    public void removeObserver(Observer o) {
        if(!list.isEmpty())
            list.remove(o);
    }

    //遍历
    @Override
    public void notifyObserver() {
        for(int i = 0; i < list.size(); i++) {
            Observer oserver = list.get(i);
            oserver.update(message);
        }
    }

    public void setInfomation(String s) {
        this.message = s;
        System.out.println("微信服务更新消息: " + s);
        //消息更新,通知所有观察者
        notifyObserver();
    }

}
class User implements Observer {

    private String name;
    private String message;

    public User(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        this.message = message;
        read();
    }

    public void read() {
        System.out.println(name + " 收到推送消息: " + message);
    }

}

 

Command Mode

Essence of: decoupling and transmits a request to send commands to the sender of the request handler through the command class, a command processing request in the call handler inside

Example: TV remote control, the remote control sends a command, the TV receives a command, process the command handler calls an internal

package com.jd.testjava.testdesignpattern;

/**
 * @author lichenyang8
 * @date 2019/5/17
 */
public class TestCommandPattern {
    public static void main(String[] args) {
        // 命令接收者Receiver
        Tv myTv = new Tv();
        // 开机命令ConcreteCommond
        CommandOn on = new CommandOn(myTv);
        // 命令控制对象Invoker
        Control control = new Control(on);
        // 开机
        control.turnOn();

    }

}

interface Command {
    void execute();
}

class Tv {
    public int currentChannel = 0;

    public void turnOn() {
        System.out.println("The televisino is on.");
    }

    public void turnOff() {
        System.out.println("The television is off.");
    }


    public void changeChannel(int channel) {
        this.currentChannel = channel;
        System.out.println("Now TV channel is " + channel);
    }
}

class CommandOn implements Command {

    private Tv myTv;


    public CommandOn(Tv tv) {
        myTv = tv;
    }


    @Override
    public void execute() {
        myTv.turnOn();
    }
}

class Control {
    private Command onCommand;


    public Control(Command on) {
        onCommand = on;
    }


    public void turnOn() {
        onCommand.execute();
    }


}

Chain of Responsibility pattern

Essence: a chain structure decouple the request sender and receiver

Example: Struts2 request processing

package com.jd.testjava.testdesignpattern;

import java.util.ArrayList;
import java.util.List;

/**
 * 处理连(责任链)
 *
 * @author lichenyang8
 * @date 2019/5/20
 */
public class TestHanderChain {
    public static void main(String args[]) {
        //设定过滤规则,对msg字符串进行过滤处理
        String msg = ":):,<script>,敏感,被就业,网络授课";
        //过滤请求
        Request request=new Request();
        //set方法,将待处理字符串传递进去
        request.setRequest(msg);
        //处理过程结束,给出的响应
        Response response=new Response();
        //设置响应信息
        response.setResponse("response:");
        //FilterChain,过滤规则形成的拦截链条
        FilterChain fc=new FilterChain();
        //规则链条添加过滤规则,采用的是链式调用
        fc.addFilter(new HTMLFilter())
                .addFilter(new SensitiveFilter())
                .addFilter(new FaceFilter());
        //按照FilterChain的规则顺序,依次应用过滤规则
        fc.doFilter(request, response,fc);
        //打印请求信息
        System.out.println(request.getRequest());
        //打印响应信息
        System.out.println(response.getResponse());
        /*
         * 处理器对数据进行处理
         * --|----|---数据--|-----|---
         * 规则1      规则2                 规则3       规则4
         */
    }

}

class Request {
    String requestStr;

    public String getRequest() {
        return requestStr;
    }

    public void setRequest(String request) {
        this.requestStr = request;
    }

}
class Response {
    String responseStr;

    public String getResponse() {
        return responseStr;
    }

    public void setResponse(String response) {
        this.responseStr = response;
    }

}
/*
 * 定义接口Filter,具体的过滤规则需要实现这个接口,最后一个参数添加的意义是我们在Main函数中:
 * fc.doFilter(request, response,fc);执行这一步的时候可以按照规则链条一次使用三个过滤规则对字符串进行处理
 * 因为
 *
 */
interface Filter {
    void doFilter(Request request,Response response,FilterChain chain);
}
class HTMLFilter implements Filter {

    @Override
    public void doFilter(Request request, Response response, FilterChain chain) {
        //将字符串中出现的"<>"符号替换成"[]"
        request.requestStr=request.requestStr
                .replace('<', '[').replace('>', ']')+
                //后面添加的是便于我们观察代码执行步骤的字符串
                "----HTMLFilter()";
        chain.doFilter(request, response,chain);
        response.responseStr+="---HTMLFilter()";
    }

}
class SensitiveFilter implements Filter{

    @Override
    public void doFilter(Request request, Response response, FilterChain chain) {
        //处理字符串中的敏感信息,将被就业和谐成就业
        request.requestStr=request.requestStr
                .replace("被就业", "就业").replace("敏感", "")+
                //后面添加的是便于我们观察代码执行步骤的字符串
                " ---sensitiveFilter()";
        chain.doFilter(request, response,chain);
        response.responseStr+="---sensitiveFilter()";
    }

}
class FaceFilter implements Filter {

    @Override
    public void doFilter(Request request, Response response, FilterChain chain) {

        //将字符串中出现的":):"转换成"^V^";
        request.requestStr = request.requestStr.replace(":):", "^V^")
                //后面添加的是便于我们观察代码执行步骤的字符串
                + "----FaceFilter()";
        chain.doFilter(request, response, chain);
        response.responseStr += "---FaceFilter()";
    }

}
class FilterChain implements Filter{
    //用List集合来存储过滤规则
    List<Filter> filters = new ArrayList<Filter>();
    //用于标记规则的引用顺序
    int index=0;
    //往规则链条中添加规则
    public FilterChain addFilter(Filter f) {
        filters.add(f);
        //代码的设计技巧:Chain链添加过滤规则结束后返回添加后的Chain,方便我们下面doFilter函数的操作
        return this;
    }
    @Override
    public void doFilter(Request request, Response response, FilterChain chain){
        //index初始化为0,filters.size()为3,不会执行return操作
        if(index==filters.size()){
            return;
        }
        //每添加一个过滤规则,index自增1
        Filter f=filters.get(index);
        index++;
        //根据索引值获取对应的规律规则对字符串进行处理
        f.doFilter(request, response, chain);
    }
}

Proxy mode

Essence: the premise of not changing the target class, the non-invasive to add new features

Example: jdk dynamic proxy

package com.jd.testjava.testdesignpattern;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author lichenyang8
 * @date 2019/5/20
 */
public class TestProxyPattern {
    public static void main(String[] args) {
        //真实对象
        Subject realSubject =  new RealSubject();

        MyInvocationHandler myInvocationHandler = new MyInvocationHandler(realSubject);
        //代理对象
        Subject proxyClass = (Subject) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Subject.class}, myInvocationHandler);

        proxyClass.sellBooks();

        proxyClass.speak();
    }
}

interface Subject {
    public int sellBooks();

    public String speak();
}
class RealSubject implements Subject{
    @Override
    public int sellBooks() {
        System.out.println("卖书");
        return 1 ;
    }

    @Override
    public String speak() {
        System.out.println("说话");
        return "张三";
    }
}
class MyInvocationHandler implements InvocationHandler {
    /**
     * 因为需要处理真实角色,所以要把真实角色传进来
     */
    Subject realSubject ;

    public MyInvocationHandler(Subject realSubject) {
        this.realSubject = realSubject;
    }

    /**
     *
     * @param proxy    代理类
     * @param method    正在调用的方法
     * @param args      方法的参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("调用代理类");
        if(method.getName().equals("sellBooks")){
            int invoke = (int)method.invoke(realSubject, args);
            System.out.println("调用的是卖书的方法");
            return invoke ;
        }else {
            String string = (String) method.invoke(realSubject,args) ;
            System.out.println("调用的是说话的方法");
            return  string ;
        }
    }
}

Decorator

Essence: Decorator (Decorator Pattern) allows new functionality to an existing object, without changing its structure. Packaging of existing class

Example: Java io in BufferedOutputStream and FileOutputStream

package com.jd.testjava.testdesignpattern;

/**
 * @author lichenyang8
 * @date 2019/5/21
 */
public class TestDecoratorPattern {
    public static void main(String[] args) {

        Shape circle = new Circle();
        ShapeDecorator redCircle = new RedShapeDecorator(new Circle());
        ShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());
        //Shape redCircle = new RedShapeDecorator(new Circle());
        //Shape redRectangle = new RedShapeDecorator(new Rectangle());
        System.out.println("Circle with normal border");
        circle.draw();

        System.out.println("\nCircle of red border");
        redCircle.draw();

        System.out.println("\nRectangle of red border");
        redRectangle.draw();
    }
}

abstract class ShapeDecorator implements Shape {
    protected Shape decoratedShape;

    public ShapeDecorator(Shape decoratedShape){
        this.decoratedShape = decoratedShape;
    }

    public void draw(){
        decoratedShape.draw();
    }
}

class RedShapeDecorator extends ShapeDecorator {

    public RedShapeDecorator(Shape decoratedShape) {
        super(decoratedShape);
    }

    @Override
    public void draw() {
        decoratedShape.draw();
        setRedBorder(decoratedShape);
    }

    private void setRedBorder(Shape decoratedShape){
        System.out.println("Border Color: Red");
    }
}
interface Shape {
    void draw();
}
class Rectangle implements Shape {

    @Override
    public void draw() {
        System.out.println("Shape: Rectangle");
    }
}
class Circle implements Shape {

    @Override
    public void draw() {
        System.out.println("Shape: Circle");
    }
}

Adapter mode

Essence: There are two

1. (interface adapter) you want to use one interface, but the interface must implement all methods, then you can use an adapter to interface to abstract empty implementation methods, and then inherited by their abstract adapter class, that is what you want to cover methods can.

2. (Class adapter) is present between the two do not match, for both connections, the mismatch becomes match

Example: HttpServletRequestWrapper 

Interface Adapter:

package com.jd.testjava.testdesignpattern;

/**
 * @author lichenyang8
 * @date 2019/5/21
 */
public class TestAdapterPattern {
    public static void main(String[] args) {
        A a = new Ashili();
        a.a();
        a.d();
    }
}
interface A {
    void a();
    void b();
    void c();
    void d();
    void e();
    void f();
}
abstract class Adapter implements A {
    public void a(){}
    public void b(){}
    public void c(){}
    public void d(){}
    public void e(){}
    public void f(){}
}
class Ashili extends Adapter {
    public void a(){
        System.out.println("实现A方法被调用");
    }
    public void d(){
        System.out.println("实现d方法被调用");
    }
}

Class Adapter

package com.jd.testjava.testdesignpattern;

/**
 * @author lichenyang8
 * @date 2019/5/21
 */
public class TestAdapterPattern {
    public static void main(String[] args) {
        Ps2 p = new Adapter(new Usber());
        p.isPs2();
    }

}

interface Ps2 {
    void isPs2();
}

interface Usb {
    void isUsb();
}

class Usber implements Usb {

    @Override
    public void isUsb() {
        System.out.println("USB口");
    }

}

class Adapter implements Ps2 {

    private Usb usb;

    public Adapter(Usb usb) {
        this.usb = usb;
    }

    @Override
    public void isPs2() {
        usb.isUsb();
    }

}

 

Guess you like

Origin blog.csdn.net/qq_29857681/article/details/90168976