设计模式

 

单例:

1、饿汉式:

类加载到内存后,就实例化一个单例,JVM保证线程安全,简单实用,推荐使用

唯一缺点:不管用到与否,类装载时就完成实例化

public class Singleton1 {
    private static final Singleton1 INSTANCE = new Singleton1();
    private Singleton1() {

    }
    public static Singleton1 getInstance(){
        return INSTANCE;
    }

    public static void main(String[] args) {
        Singleton1 instance1 = Singleton1.getInstance();
        Singleton1 instance2 = Singleton1.getInstance();
        System.out.println(instance1==instance2);
    }
}

2、懒汉式

第一种:

public class Singleton2 {
    private static Singleton2 INSTANCE;

    private Singleton2() {
    }

    public static synchronized Singleton2 getInstance() {
        if (INSTANCE == null) {
            try {
                Thread.sleep(100);
            } catch (Exception e) {
                e.printStackTrace();
            }
            INSTANCE = new Singleton2();
        }
        return INSTANCE;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 30; i++) {
            new Thread(new Runnable() {
                public void run() {
                    System.out.println(Singleton2.getInstance().hashCode());
                }
            }).start();
        }

    }
}

懒汉式升级版:

public class Singleton2 {
    private static Singleton2 INSTANCE;

    private Singleton2() {
    }

    public static Singleton2 getInstance() {
        if (INSTANCE == null) {
            synchronized (Singleton2.class) {
                if(INSTANCE==null) {
                    try {
                        Thread.sleep(100);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    INSTANCE = new Singleton2();
                }
            }
        }
        return INSTANCE;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 30; i++) {
            new Thread(new Runnable() {
                public void run() {
                    System.out.println(Singleton2.getInstance().hashCode());
                }
            }).start();
        }

    }
}

3、静态内部类:懒加载(内部类只会在jvm中加载一次,所以是线程安全的)

public class Singleton3 {
    private Singleton3(){

    }
    private static class InnerSingle{
        private static final Singleton3 INSTANCE = new Singleton3();
    }
    public static Singleton3 getInstance(){
        return InnerSingle.INSTANCE;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 30; i++) {
            new Thread(new Runnable() {
                public void run() {
                    System.out.println(Singleton3.getInstance().hashCode());
                }
            }).start();
        }
    }
}

4、枚举单例:java创始人编写

public enum Singleton4 {
    INSTANCE;
    public void m(){}

    public static void main(String[] args) {
        for (int i = 0; i < 30; i++) {
            new Thread(new Runnable() {
                public void run() {
                    System.out.println(Singleton4.INSTANCE.hashCode());
                }
            }).start();
        }
    }
}

责任链

普通的责任链模式:

public class ChainPar {
    public static void main(String[] args) {
        Msg m = new Msg();
        m.setMsg("大家好:<script>,,欢迎访问 mashbing.com 大家都是996.:)");
        System.out.println(m);
        // 处理msg

//        List<Filter> list = new ArrayList<>();
//        list.add(new HTMLFilter());
//        list.add(new SensitiveFilter());
//        for (Filter filter : list) {
//            filter.doFilter(m);
//        }

        FilterChain fc = new FilterChain();
        fc.add(new HTMLFilter())
                .add(new SensitiveFilter());

        FilterChain fc2 = new FilterChain();
        fc2.add(new FaceFilter())
                .add(new URLFilter());
        fc.add(fc2);
        fc.doFilter(m);


        System.out.println(m);
    }
}

class Msg {
    private String name;
    private String msg;

    @Override
    public String toString() {
        return "Msg{" +
                "name='" + name + '\'' +
                ", msg='" + msg + '\'' +
                '}';
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

}


interface Filter {
    boolean doFilter(Msg m);
}

class HTMLFilter implements Filter {

    @Override
    public boolean doFilter(Msg m) {
        String r = m.getMsg();
        r = r.replace('<', '[');
        r = r.replace('>', ']');
        m.setMsg(r);
        return true;
    }
}

class SensitiveFilter implements Filter {

    @Override
    public boolean doFilter(Msg m) {
        String r = m.getMsg();
        r = r.replace("996", "955");
        m.setMsg(r);
        return false;
    }
}

class FaceFilter implements Filter {

    @Override
    public boolean doFilter(Msg m) {
        String r = m.getMsg();
        r = r.replace(":)", "^V^");
        m.setMsg(r);
        return true;
    }
}

class URLFilter implements Filter {

    @Override
    public boolean doFilter(Msg m) {
        String r = m.getMsg();
        r = r.replace("mashibing.com", "http://mashibing.com");
        m.setMsg(r);
        return true;
    }
}

class FilterChain implements Filter{
    List<Filter> list = new ArrayList<>();
    public FilterChain add(Filter filter){
        list.add(filter);
        return this;
    }
    public boolean doFilter(Msg m){
        for (Filter filter : list) {
            if(!filter.doFilter(m)) return false;
        }
        return true;
    }

}

servlet责任链模式原理:

public class serverFilters {
    public static void main(String[] args) {

        Request request = new Request();
        request.setStr("hello world");
        Response response = new Response();
        response.setStr("hadoop flink");

        FilterChain fc = new FilterChain();
        fc.add(new HTMLFilter())
                .add(new SensitiveFilter())
                .add(new FaceFilter())
                .add(new URLFilter());
        fc.doFilter(request, response);
        System.out.println(request.getStr());
        System.out.println(response.getStr());
    }
}


class Request {
    String str;

    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }

    @Override
    public String toString() {
        return "Request{" +
                "str='" + str + '\'' +
                '}';
    }
}

class Response {
    String str;

    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }

    @Override
    public String toString() {
        return "Response{" +
                "str='" + str + '\'' +
                '}';
    }
}


interface Filter {
    boolean doFilter(Request request, Response response, FilterChain filterChain);
}

class HTMLFilter implements Filter {

    @Override
    public boolean doFilter(Request request, Response response, FilterChain filterChain) {
        String str = request.getStr();
        str += "HTMLFilter request";
        request.setStr(str);
        filterChain.doFilter(request, response);
        String str1 = response.getStr();
        str1 += "HTMLFilter response";
        response.setStr(str1);
        return true;
    }
}


class SensitiveFilter implements Filter {

    @Override
    public boolean doFilter(Request request, Response response, FilterChain filterChain) {
        String str = request.getStr();
        str += "SensitiveFilter request";
        request.setStr(str);
        filterChain.doFilter(request, response);
        String str1 = response.getStr();
        str1 += "SensitiveFilter response";
        response.setStr(str1);
        return true;
    }
}

class FaceFilter implements Filter {

    @Override
    public boolean doFilter(Request request, Response response, FilterChain filterChain) {
        String str = request.getStr();
        str += "FaceFilter request";
        request.setStr(str);
        filterChain.doFilter(request, response);
        String str1 = response.getStr();
        str1 += "FaceFilter response";
        response.setStr(str1);
        return true;
    }
}

class URLFilter implements Filter {

    @Override
    public boolean doFilter(Request request, Response response, FilterChain filterChain) {
        String str = request.getStr();
        str += "URLFilter request";
        request.setStr(str);
        filterChain.doFilter(request, response);
        String str1 = response.getStr();
        str1 += "URLFilter response";
        response.setStr(str1);
        return true;
    }
}

class FilterChain {
    List<Filter> list = new ArrayList<>();
    int index = 0;

    public FilterChain add(Filter filter) {
        list.add(filter);
        return this;
    }

    public boolean doFilter(Request request, Response response) {
        if (index == list.size()) return false;
        Filter filter = list.get(index);
        index++;
        filter.doFilter(request, response, this);
        return true;
    }

}

代理模式:

静态代理:

public class TankProxy implements Moveable {
    @Override
    public void move() {
        System.out.println("Tank moving claclacla...");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new TankTimeProxy(
                new TankLogProxy(
                        new TankProxy()
                )
        ).move();
    }
}

public interface Moveable {
    void move();
}

public class TankLogProxy implements Moveable {
    Moveable m;

    public TankLogProxy(Moveable m) {
        this.m = m;
    }

    @Override
    public void move() {
        System.out.println("moving start");
        m.move();
        System.out.println("moving end");
    }
}

public class TankTimeProxy implements Moveable {
    Moveable m;

    public TankTimeProxy(Moveable m) {
        this.m = m;
    }

    @Override
    public void move() {
        long start = System.currentTimeMillis();
        m.move();
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }
}

代理者和被代理者都实现了moveable接口

缺点:只能代理moveable接口类型

jdk动态代理:

public class DanimicProxy implements Movable {
    @Override
    public void move() {
        System.out.println("Tank moving claclacla...");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        DanimicProxy danimicProxy = new DanimicProxy();
        Movable m = (Movable) Proxy.newProxyInstance(DanimicProxy.class.getClassLoader(),
                new Class[]{Movable.class},
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("method " + method.getName() + " start..");
                        Object o = method.invoke(danimicProxy, args);
                        System.out.println("method " + method.getName() + " end!");
                        return o;
                    }
                });
        m.move();
    }
}

interface Movable {
    void move();
}

另一种写法

public class DanimicProxy implements Movable {
    @Override
    public void move() {
        System.out.println("Tank moving claclacla...");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        DanimicProxy danimicProxy = new DanimicProxy();
        Movable m = (Movable) Proxy.newProxyInstance(DanimicProxy.class.getClassLoader(),
                new Class[]{Movable.class},
                new MyInvocationHandler(danimicProxy));
        m.move();
    }
}

// 此类就是代理类
class MyInvocationHandler implements InvocationHandler {
    private DanimicProxy danimicProxy;

    public MyInvocationHandler(DanimicProxy danimicProxy) {
        this.danimicProxy = danimicProxy;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("method " + method.getName() + " start..");
        Object o = method.invoke(danimicProxy, args);
        System.out.println("method " + method.getName() + " end!");
        return o;
    }
}

interface Movable {
    void move();
}

以上两例中 m.move()方法实际上是调用了MyInvocationHandler类的invoke方法。如何实现的呢?请往下看

将以上的main方法修改为:

也就是加了一行代码:

System.getProperties().put("jdk.proxy.ProxyGenerator.saveGeneratedFiles","true");

会生成一个字节文件,idea会自动进行反编译,可以查看其内容。

第19行的var1其实就是下面的danimicProxy。或者说是代理类。

新生成的文件继承了Proxy父类,并实现了movable接口。20行调用了super(var1)方法。就是将danimicProxy传递给父类Proxy进行初始化。33行的move方法其实就是重写的实现movable接口中的move方法。为什么会实现movable接口,因为我在main方法中指定了必须实现Movable接口。move方法的35行调用了super.h.invoke()方法,super.h是什么意思呢,这个h就是我们20行super(var1)中的var1。这个var1就是我们的代理类的一个对象,它里面有一个invoke方法。此处调用的就是这个invoke方法。这就是m.move如何调用了我们写的MyInvocationHandler类的invoke方法的原理。

此处movable接口可以有多个抽象方法。然后在MyInvocationHandler的invoke方法中根据method.getName()方法获取每个接口中每个方法的名称,然后根据这个名称,可以实现不同方法实现不同功能。如:

class MyInvocationHandler implements InvocationHandler {
    private DanimicProxy danimicProxy;

    public MyInvocationHandler(DanimicProxy danimicProxy) {
        this.danimicProxy = danimicProxy;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object o = null;
        if (method.getName().equals("move")) {
            System.out.println("method " + method.getName() + " start..");
            o = method.invoke(danimicProxy, args);
            System.out.println("method " + method.getName() + " end!");
        } else if (method.getName().equals("stop")) {
            System.out.println("method " + method.getName() + " start..");
            o = method.invoke(danimicProxy, args);
            System.out.println("method " + method.getName() + " end!");
        }
        return o;
    }
}

interface Movable {
    void move();

    void stop();
}

我们还没说MyInvocationHandler类中的invoke方法的参数:先说第二个参数:这个就是接口中的抽象方法,第三个参数:这个就是第二个参数的方法需要的参数。第一个参数:此处需要看看是谁调用了invoke方法,找到调用invoke方法的人,可以找到其传给invoke方法的参数。可以看到是super.h.invoke()调用了invoke方法。传进去的第一个参数是this.其实就是下图中的m。

上面我们讲了中间自动生成了一个类,即$Proxy类。那到底是怎么生成的呢?

此处比较复杂,不想洗阐述,但可以简单说一说:

其中间会调用到jdk.internal.org.objectweb.asm类中的内容,即asm,asm可以直接修改类编译后的字节文件,正式因为java的sam可以直接修改类编译后的字节文件,所以java也被称为动态语言。那什么叫动态语言,即程序运行过程中可以直接修改类编译后的的字节码。动态语言不是靠反射体现的,反射是可以获取,但不可以修改。

以上就是jdk的动态代理,要有其他类型的动态代理

cglib动态代理

jdk的反射动态代理需要实现一个接口;而cglib却不需要。

public class CglibProxy {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Cat.class);
        enhancer.setCallback(new TimeMethodInterceptor());
        Cat cat = (Cat) enhancer.create();
        cat.move();
    }
}

class TimeMethodInterceptor implements MethodInterceptor{

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        // System.out.println(obj.getClass().getSuperclass().getName());
        System.out.println("before");
        Object result = null;
        result = proxy.invokeSuper(obj,args);
        System.out.println("after");
        return result;
    }
}

class Cat{
    public void move(){
        System.out.println("Tank moving claclacla...");
        try {
            Thread.sleep(12);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}

此方法如何获取被代理的类呢?就是上面注释的代码

Builder

public class Terrain {
    Wall w;
    Fort f;
    Mine m;
}

class Wall {
    int x, y, w, h;

    public Wall(int x, int y, int w, int h) {
        this.x = x;
        this.y = y;
        this.w = w;
        this.h = h;
    }
}

class Fort {
    int x, y, w, h;

    public Fort(int x, int y, int w, int h) {
        this.x = x;
        this.y = y;
        this.w = w;
        this.h = h;
    }
}

class Mine {
    int x, y, w, h;

    public Mine(int x, int y, int w, int h) {
        this.x = x;
        this.y = y;
        this.w = w;
        this.h = h;
    }
}
public interface TerrainBuilder {
    TerrainBuilder builderWall();
    TerrainBuilder builderFort();
    TerrainBuilder builderMine();

    Terrain build();
}
public class ComplexTerrainBuilder implements TerrainBuilder {
    Terrain terrain = new Terrain();

    @Override
    public TerrainBuilder builderWall() {
        terrain.w = new Wall(1, 2, 3, 4);
        return this;
    }

    @Override
    public TerrainBuilder builderFort() {
        terrain.f = new Fort(1, 2, 3, 4);
        return this;
    }

    @Override
    public TerrainBuilder builderMine() {
        terrain.m = new Mine(1, 2, 3, 4);
        return this;
    }

    @Override
    public Terrain build() {
        return terrain;
    }
}
public class Main {
    public static void main(String[] args) {
        ComplexTerrainBuilder builder = new ComplexTerrainBuilder();
        Terrain t = builder.builderFort().builderMine().builderWall().build();


    }
}

Builder案例:

public class Person {
    int id;
    String name;
    int age;
    double weight;
    int score;
    Location loc;

    public Person() {

    }

    public static class PersonBuilder {
        Person p = new Person();

        public PersonBuilder basicInfo(int id, String name, int age) {
            p.id = id;
            p.name = name;
            p.age = age;
            return this;
        }

        public PersonBuilder weight(double weight) {
            p.weight = weight;
            return this;
        }

        public PersonBuilder score(int score) {
            p.score = score;
            return this;
        }

        public PersonBuilder loc(String street, String roomNo) {
            p.loc = new Location(street, roomNo);
            return this;
        }

        public Person build() {
            return p;
        }
    }
}

class Location {
    String street;
    String roomNo;

    public Location() {
    }

    public Location(String street, String roomNo) {
        this.street = street;
        this.roomNo = roomNo;
    }
}
public class PersonMain {
    public static void main(String[] args) {
        Person p = new Person.PersonBuilder()
                .basicInfo(1,"zhangsan",15)
                .score(20)
                .weight(200)
                .build();
    }
}

观察者

public class TankFireEvent {
    Tank tank;

    public Tank getSource() {
        return tank;
    }

    public TankFireEvent(Tank tank) {
        this.tank = tank;
    }
}
public class TankFireHandler implements TankFireObserver {
    @Override
    public void actionOnFire(TankFireEvent e) {
        Tank t = e.getSource();
        t.fire();
    }
}
public interface TankFireObserver {
    void actionOnFire(TankFireEvent event);
}

Adapter(Wrapper)

public class Main {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("path");
        InputStreamReader isr = new InputStreamReader(fis);
        BufferedReader br = new BufferedReader(isr);
        String line = br.readLine();
        while (line != null && !line.equals("")) {
            System.out.println(line);
        }
        br.close();
    }
}

桥接模式

public abstract class Gift {
    GiftImp giftImp;
}
public abstract class GiftImp {
}
public class WarmGift extends Gift{
    public WarmGift(GiftImp giftImp){
        this.giftImp = giftImp;
    }
}
public class WildGift extends Gift {
    public WildGift(GiftImp giftImp) {
        this.giftImp = giftImp;
    }
}
public class Book extends Gift {
}
public class Floor extends GiftImp {
}
public class GG {
    public void chase(MM mm){
        WarmGift g = new WarmGift(new Floor());
    }
}

此处的MM没有具体实现,此处仅仅表明桥接模式的用法即可。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值