设计模式

单例模式

懒汉式:

package com.koma.mode.singleton;

/**
 * Create by koma on 2017/12/31
 * 单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
 * 懒汉式。
 */
public class Singleton {
    // 把无参构造方法私有化,使得外部不能new。
    private Singleton(){}

    private static Singleton instance;

    public static Singleton getInstance() {
        if(instance==null){
            instance=new Singleton();
        }
        return instance;
    }
}

单线程环境下这样写没问题,多线程环境下呢???所有需要同步:

public static synchronized Singleton getInstance() {
        if(instance==null){
            instance=new Singleton();
        }
        return instance;
    }

完全可以,但是每次调用getInstance方法,都需要同步,效率肯定不高,所以就有了DCL(双重检查锁):

public static Singleton getInstance() {
        if(instance==null){
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance=new Singleton();
                }
            }
        }
        return instance;
    }

这样写真的就线程安全吗???当在没有同步的情况下读取一个共享变量instance肯定是有问题的,如果对instance变量加上volatile关键字就可以用DCL,最终的DCL:

public class Singleton {
    // 把无参构造方法私有化,使得外部不能new。
    private Singleton(){}

    private static volatile Singleton instance;

    public static Singleton getInstance() {
        if(instance==null){
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance=new Singleton();
                }
            }
        }
        return instance;
    }
}

饿汉式:

public class Singleton {
    private static Singleton instance = new Singleton();

    public static Singleton getInstance() {
        return instance;
    }

    private Singleton() {
    }
}

饿汉式:类创建的同时就已经创建好一个静态的对象供系统使用,肯定线程安全的。

JDK中单例:

JDK中Runtime类就是使用饿汉式单例模式设计的。

工厂模式

简单工厂模式:

实现一个计算器,定义一个运算类,加减乘除等运算继承这个运算类就可以了,再定义一个工厂生产这些运算类。

package com.koma.mode.factory.simple;

/**
 * Create by koma on 2017/12/17
 */
public abstract class Operation {

    private Long numberA;
    private Long numberB;

    public abstract long getResult();

    public Long getNumberA() {
        return numberA;
    }

    public void setNumberA(Long numberA) {
        this.numberA = numberA;
    }

    public Long getNumberB() {
        return numberB;
    }

    public void setNumberB(Long numberB) {
        this.numberB = numberB;
    }
}
package com.koma.mode.factory.simple;

/**
 * Create by koma on 2017/12/17
 */
public class OperationAdd extends Operation {

    @Override
    public long getResult() {
        return getNumberA() + getNumberB();
    }
}
package com.koma.mode.factory.simple;

/**
 * Create by koma on 2017/12/17
 */
public class OperationDiv extends Operation {

    @Override
    public long getResult() {
        if (getNumberB() != 0) {
            return getNumberA() / getNumberB();
        }
        throw new IllegalArgumentException("除数不能为0");
    }
}
package com.koma.mode.factory.simple;

/**
 * Create by koma on 2017/12/17
 * 使用工厂来生产对象,不需要自己new对象。
 */
public class SimpleFactory {
    public static Operation createOperation(String operate) {
        Operation operation = null;
        switch (operate) {
            case "+":
                operation = new OperationAdd();
                break;
            case "-":
                operation=new OperationSub();
                break;
            case "*":
                operation=new OperationMul();
                break;
            case "/":
                operation=new OperationDiv();
                break;
            default:
                throw new IllegalArgumentException("操作符不对!");
        }
        return operation;
    }
}

缺点:判断太多了,每增加一个运算类都要增加判断运算符。
可以使用反射来改进,就不用那么多的判断了。

public static Operation createOperation(String clazzPath) {
        Operation operation = null;
        try {
            // 通过类的全路径得到类的class对象,
            Class<?> aClass = Class.forName(clazzPath);
            operation=(Operation) aClass.newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        return operation;
    }

抽象工厂

下面使用切换数据库来举例:

package com.koma.mode.factory.abstractor;

/**
 * Create by koma on 2017/12/31
 */
public interface IUser {
    public void insertUser(User user);
    public void getUser(int id);
}
package com.koma.mode.factory.abstractor;

/**
 * Create by koma on 2017/12/31
 */
public interface IFactory {
    IUser createUser();
}
package com.koma.mode.factory.abstractor;

/**
 * Create by koma on 2017/12/31
 */
public class MysqlUser implements IUser {
    @Override
    public void insertUser(User user) {
        System.out.println("mysql 数据库插入user");
    }

    @Override
    public void getUser(int id) {
        System.out.println("mysql 数据库得到user");
    }
}
package com.koma.mode.factory.abstractor;

/**
 * Create by koma on 2017/12/31
 */
public class OracleUser implements IUser {
    @Override
    public void insertUser(User user) {
        System.out.println("oracle 数据库插入user");
    }

    @Override
    public void getUser(int id) {
        System.out.println("oracle 数据库得到user");
    }
}
package com.koma.mode.factory.abstractor;

/**
 * Create by koma on 2017/12/31
 */
public class MysqlFactory implements IFactory {
    @Override
    public IUser createUser() {
        return new MysqlUser();
    }
}
package com.koma.mode.factory.abstractor;

/**
 * Create by koma on 2017/12/31
 */
public class OracleFactory implements IFactory {
    @Override
    public IUser createUser() {
        return new OracleUser();
    }
}
package com.koma.mode.factory.abstractor;

/**
 * Create by koma on 2017/12/27
 * 抽象工厂模式:提供一个创建一系列相关或互相依赖对象的接口,而无需指定他们具体的类。
 */
public class AbstractFactory {
    public static void main(String[] args) {
        User user = new User();
        // 如果要切换数据库,只需要在这换一下数据库。
        IFactory factory = new OracleFactory();
        IUser iUser = factory.createUser();
        iUser.insertUser(user);
    }
}

JDK中工厂模式:

  • Arrays.asList()
  • Calendar.getInstance()

装饰模式

package com.koma.mode.decorator.demo;

/**
 * Create by koma on 2017/12/19
 */
public abstract class Component {
    public abstract void opration();
}
package com.koma.mode.decorator.demo;

/**
 * Create by koma on 2017/12/19
 */
public class ConcreateConponent extends Component {
    @Override
    public void opration() {
        System.out.println("具体对象的操作");
    }

}
package com.koma.mode.decorator.demo;

/**
 * Create by koma on 2017/12/19
 * 装饰模式:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
 */
public abstract class Decorator extends Component{
    private Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void opration() {
        if (component != null) {
            component.opration();
        }
    }
}
package com.koma.mode.decorator.demo;

/**
 * Create by koma on 2017/12/19
 */
public class ConcreateDecoratorA extends Decorator {

    public ConcreateDecoratorA(Component component) {
        super(component);
    }

    @Override
    public void opration() {
        // 首先运行原Component类的opration方法,再执行本类的功能,相当于对Component类进行了装饰。
        super.opration();
        addedState();
    }

    private void addedState(){
        System.out.println("具体装饰A的操作添加state功能");
    }
}
package com.koma.mode.decorator.demo;

/**
 * Create by koma on 2017/12/19
 */
public class ConcreateDecoratorB extends Decorator {
    public ConcreateDecoratorB(Component component) {
        super(component);
    }

    @Override
    public void opration() {
        super.opration();
        System.out.println("装饰B");
    }
}
package com.koma.mode.decorator.demo;

/**
 * Create by koma on 2017/12/19
 */
public class Test {
    public static void main(String[] args) {
        Component component=new ConcreateConponent();
        ConcreateDecoratorA decoratorA=new ConcreateDecoratorA(component);
        ConcreateDecoratorB decoratorB=new ConcreateDecoratorB(decoratorA);
        decoratorB.opration();
    }
}

装饰模式完全符合开放关闭原则,动态的扩展功能。

JDK中装饰模式:

IO类库设计就是很典型的装饰模式运用:
抽象构建角色(component):InputStream
具体构建(concrete component):ByteArrayInputStream、FileInputStream等。
抽象装饰角色(decorator):FilterInputStream
具体装饰角色(concrete decorator):BufferedInputStream等。

适配器模式

package com.koma.mode.adapter;

/**
 * Create by koma on 2017/12/28
 * 运动员抽象类
 */
public abstract class Player {
    private String name;

    public Player(String name) {
        super();
        this.name = name;
    }
    public abstract void attack();
    public abstract void defence();
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
package com.koma.mode.adapter;

/**
 * Create by koma on 2017/12/28
 * NBA中锋
 */
public class Center extends Player {

    public Center(String name) {
        super(name);
    }

    @Override
    public void attack() {
        System.out.println(getName()+"进攻");
    }

    @Override
    public void defence() {
        System.out.println(getName()+"防守");
    }

}
package com.koma.mode.adapter;

/**
 * Create by koma on 2017/12/28
 * 外籍中锋,听不懂英语
 */
public class ForeignCenter {
    private String name;

    public ForeignCenter(String name) {
        super();
        this.name = name;
    }

    public void foreignAttack(){
        System.out.println(name+"进攻");
    }

    public void foreignDefence(){
        System.out.println(name+"防守");
    }
}
package com.koma.mode.adapter;

/**
 * Create by koma on 2017/12/28
 * 外籍运动员听不懂英语,需要一个翻译,这个翻译就是适配器
 */
public class Adapter extends Player{

    private ForeignCenter foreignCenter;

    public Adapter(String name) {
        super(name);
        foreignCenter=new ForeignCenter(name);
    }

    @Override
    public void attack() {
        foreignCenter.foreignAttack();
    }

    @Override
    public void defence() {
        foreignCenter.foreignDefence();
    }

}
package com.koma.mode.adapter;

/**
 * Create by koma on 2017/12/28
 */
public class Test {
    public static void main(String[] args) {
        Player player=new Forwards("巴蒂尔");
        player.attack();
        player.defence();
        // 姚明通过翻译就能和队友教练交流了
        Player player2=new Adapter("姚明");
        player2.attack();
        player2.defence();
    }
}

JDK中适配器模式

还是IO流中运用:
ByteArrayOutputStream类就是一个适配器,ByteArrayOutputStream继承了OutputStream类,同时持有一个对byte数组的引用,把一个byte数组的接口适配成OutputStream类型的接口。

代理模式

静态代理

package com.koma.mode.proxy.staticproxy;

/**
 * Create by koma on 2017/12/20
 * 被追求者
 */
public class Girl {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
package com.koma.mode.proxy.staticproxy;

/**
 * Create by koma on 2017/12/20
 * 送礼物
 */
public interface GiveGift {
    void giveDolls();
    void giveFlowers();
}
package com.koma.mode.proxy.staticproxy;

/**
 * Create by koma on 2017/12/20
 * 追求者
 */
public class Pursuit implements GiveGift {
    private Girl giil;

    public Pursuit(Girl giil) {
        this.giil = giil;
    }

    @Override
    public void giveDolls() {
        System.out.println(giil.getName()+" 送熊!");
    }

    @Override
    public void giveFlowers() {
        System.out.println(giil.getName()+" 送花!");
    }
}
package com.koma.mode.proxy.staticproxy;

/**
 * Create by koma on 2017/12/20
 * 代理模式:为其他对象提供一种代理以控制对这个对象的访问。
 * 追求者害羞,请求一个代理,送礼物其实是追求者送的
 */
public class Proxy implements GiveGift {

    private Pursuit pursuit;

    public Proxy(Girl girl) {
        this.pursuit = new Pursuit(girl);
    }

    @Override
    public void giveDolls() {
        // 可以控制权限,增加功能
        pursuit.giveDolls();
    }

    @Override
    public void giveFlowers() {
        pursuit.giveFlowers();
    }
}
package com.koma.mode.proxy.staticproxy;

/**
 * Create by koma on 2017/12/20
 */
public class Test {
    public static void main(String[] args) {
        Girl girl=new Girl();
        girl.setName("玲玲");
        // 代理对象送礼物给玲玲
        Proxy proxy=new Proxy(girl);
        proxy.giveDolls();
        proxy.giveFlowers();
    }
}

动态代理

package com.koma.mode.proxy.dynamicproxy;

/**
 * Create by koma on 2017/12/20
 */
public interface BookFacade {
    void addBook();
}
package com.koma.mode.proxy.dynamicproxy;

/**
 * Create by koma on 2017/12/20
 */
public class BookFacadeImpl implements BookFacade {
    @Override
    public void addBook() {
        System.out.println("添加图书!");
    }
}
package com.koma.mode.proxy.dynamicproxy;

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

/**
 * Create by koma on 2017/12/20
 */
public class BookProxy implements InvocationHandler {

    private Object target;

    public Object bind(Object target) {
        this.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("预处理操作——————");
        System.out.println(proxy.getClass().getName());
        return method.invoke(target, args);
    }
}
package com.koma.mode.proxy.dynamicproxy;

/**
 * Create by koma on 2017/12/20
 */
public class Test {
    public static void main(String[] args) {
        BookFacade bookFacade=new BookFacadeImpl();
        BookProxy bookProxy=new BookProxy();
        BookFacade proxy = (BookFacade)bookProxy.bind(bookFacade);
        proxy.addBook();
    }
}

动态代理使用反射技术,Spring AOP中典型的使用动态代理技术。

责任链模式

使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

package com.koma.mode.cor;

/**
 * Create by koma on 2017/12/31
 */
public abstract class Handler {
    protected Handler handler;

    public Handler() {
    }

    public Handler(Handler handler) {
        this.handler = handler;
    }

    public abstract void handlerRequest(int request);

    public void setHandler(Handler handler) {
        this.handler = handler;
    }
}
package com.koma.mode.cor;

/**
 * Create by koma on 2017/12/31
 */
public class ConcreteHandler1 extends Handler {
    @Override
    public void handlerRequest(int request) {
        if (request < 0) {
            System.out.println("我处理小于0: "+request);
        } else {
            if (handler != null) {
                handler.handlerRequest(request);
            }
        }
    }
}
package com.koma.mode.cor;

/**
 * Create by koma on 2017/12/31
 */
public class ConcreteHandler2 extends Handler {

    @Override
    public void handlerRequest(int request) {
        if (request >= 0 && request < 10) {
            System.out.println("我处理<=request<10: "+request);
        } else {
            if (handler != null) {
                handler.handlerRequest(request);
            }
        }
    }
}
package com.koma.mode.cor;

/**
 * Create by koma on 2017/12/31
 */
public class ConcreteHandler3 extends Handler {
    @Override
    public void handlerRequest(int request) {
        if (request >= 10) {
            System.out.println("我处理大于10: "+request);
        } else {
            if (handler != null) {
                handler.handlerRequest(request);
            }
        }
    }
}
package com.koma.mode.cor;

/**
 * Create by koma on 2017/12/31
 * 责任链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。
 *           将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
 */
public class Cor {
    public static void main(String[] args) {
        int[] arr={-3,1,-2,123,39,3,-5};
        ConcreteHandler1 concreteHandler1=new ConcreteHandler1();
        ConcreteHandler2 concreteHandler2=new ConcreteHandler2();
        ConcreteHandler3 concreteHandler3=new ConcreteHandler3();
        concreteHandler1.setHandler(concreteHandler2);
        concreteHandler2.setHandler(concreteHandler3);

        for (int i : arr) {
        // 总最小的处理者开始处理,如果处理不了,由上层处理,一直传递上去,直到可以处理为止。
            concreteHandler1.handlerRequest(i);
        }
    }
}

总之一句话要面向接口和抽象类编程,不要面向实现编程。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值