单例模式
懒汉式:
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);
}
}
}
总之一句话要面向接口和抽象类编程,不要面向实现编程。