责任链模式
一个请求有多个对象来处理,这些对象是一条链,但具体由哪个对象来处理,根据条件判断来确定,如果不能处理会传递给该链中的下一个对象,直到有对象处理它为止
使用场景
1)有多个对象可以处理同一个请求,具体哪个对象处理该请求待运行时刻再确定
2)在不明确指定接收者的情况下,向多个对象中的一个提交一个请求
3)可动态指定一组对象处理请求,客户端可以动态创建职责链来处理请求
public class Chain {public abstract class Handler {private Handler nextHandler;// 当前领导能审批通过的最多天数public int maxDay;protected Handler(int maxDay) {this.maxDay = maxDay;}//设置责任链中下一个处理请求的对象public void setNextHandler(Handler handler) {nextHandler = handler;}protected void handleRequest(int day) {if (day <= maxDay) {reply(day);} else {if (nextHandler != null) {//审批权限不够,继续上报nextHandler.handleRequest(day);} else {System.out.println("没有更高的领导审批了");}}}protected abstract void reply(int day);}class ProjectManager extends Handler {public ProjectManager(int day) {super(day);}@Overrideprotected void reply(int day) {System.out.println(day + "天请假,项目经理直接审批通过");}}class DepartmentManager extends Handler {public DepartmentManager(int day) {super(day);}@Overrideprotected void reply(int day) {System.out.println(day + "天请假,部门经理审批通过");}}class GeneralManager extends Handler {public GeneralManager(int day) {super(day);}@Overrideprotected void reply(int day) {System.out.println(day + "天请假,总经理直接审批通过");}}public static void main(String[] strings) {Chain chain = new Chain();Handler projectManager = chain.new ProjectManager(3);Handler departmentManager = chain.new DepartmentManager(5);Handler generalManager = chain.new GeneralManager(15);//创建职责链projectManager.setNextHandler(departmentManager);departmentManager.setNextHandler(generalManager);//发起请假请求projectManager.handleRequest(4);}
}
Buidler(建造者)模式
一种创建型的设计模式.,通常用来将一个复杂的对象的构造过程分离, 让使用者可以根据需要选择创建过程.另外, 当这个复杂的对象的构造包含很多可选参数时, 也可以使用建造者模式
public class AlerDialog {private String title;private String message;public AlerDialog(Builder builder) {
// View.inflate()this.title = builder.title;this.message = builder.message;}public static class Builder {private String title;private String message;public Builder setTitle(String title) {this.title = title;return this;}public Builder setMessage(String message) {this.message = message;return this;}public AlerDialog build() {return new AlerDialog(this);}}
}new AlerDialog.Builder().setTitle("").setMessage("").build();
适配器模式:
把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起使用的类能够一起工作。
适配器就是一种适配中间件,它存在于不匹配的二者之间,用于连接二者,将不匹配变得匹配,简单点理解就是平常所见的转接头,转换器之类的存在。
类适配器
原理:通过继承来实现适配器功能。
类适配器使用对象继承的方式,是静态的定义方式
对于类适配器,适配器可以重定义Adaptee的部分行为,使Adaptee有了sampleOperation2()
对于类适配器,仅仅引入了一个对象,并不需要额外的引用来间接得 到 Adaptee
对于类适配器,由于适配器直接继承了Adaptee,使得适配器不能和 Adaptee的子类一起工作
public interface Target {void sampleOperation1();void sampleOperation2();
}
public class Adaptee {public void sampleOperation1() {System.out.println("sampleOperation1");}
}
public class Adapter extends Adaptee implements Target {@Overridepublic void sampleOperation2() {System.out.println("sampleOperation2");}}
public class MyClass {public static void main(String[] args) {Adapter adapter = new Adapter();adapter.sampleOperation1();adapter.sampleOperation2();}
}
对象适配器
与类的适配器模式一样,对象的适配器模式把被适配的类的API转换成为目标类的API,与类的适配器模式不同的是,对象的适配器模式不是使用继承关系连接到Adaptee类,而是使用委派关系连接到Adaptee类。
对象适配器使用对象组合的方式,是动态组合的方式
对于对象适配器,一个适配器(adaptee)可以把多种不同的源适配到同一个目标
对于对象适配器,要重定义Adaptee的行为比较困难
对于对象适配器,需要额外的引用来间接得到Adaptee。
public interface Target {void sampleOperation1();void sampleOperation2();
}public class Adaptee {public void sampleOperation1() {System.out.println("sampleOperation1");}
}public class Adapter implements Target {private Adaptee mAdaptee;public Adapter(Adaptee adaptee) {mAdaptee = adaptee;}@Overridepublic void sampleOperation1() {mAdaptee.sampleOperation1();}@Overridepublic void sampleOperation2() {System.out.println("sampleOperation2");}}public class MyClass {public static void main(String[] args) {Adapter adapter =new Adapter(new Adaptee());adapter.sampleOperation1();adapter.sampleOperation2();}
}
代理模式
通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,扩展目标对象的功能。在调用这个方法前作的前置处理(统一的流程代码放到代理中处理)。调用这个方法后做后置处理。
这里使用到编程中的一个思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式来扩展该方法。
这里使用到编程中的一个思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式来扩展该方法。
动态代理的用途与装饰模式很相似,就是为了对某个对象进行增强。所有使用装饰者模式的案例都可以使用动态代理来替换。
/*** subject(抽象主题角色):* 真实主题与代理主题的共同接口。*/
interface Subject {void sellBook();
}/*** ReaISubject(真实主题角色):* 定义了代理角色所代表的真实对象。*/
public class RealSubject implements Subject {@Overridepublic void sellBook() {System.out.println("出版社卖书");}
}/*** Proxy(代理主题角色):* 含有对真实主题角色的引用,代理角色通常在将客* 户端调用传递给真实主题对象之前或者之后执行某些* 操作,而不是单纯返回真实的对象。*/
public class ProxySubject implements Subject {private RealSubject realSubject;@Overridepublic void sellBook() {if (realSubject == null) {realSubject = new RealSubject();}sale();realSubject.sellBook();give();}public void sale() {System.out.println("打折");}public void give() {System.out.println("送优惠券");}
}public class Main {public static void main(String[] args) {//静态代理(我们自己静态定义的代理类)ProxySubject proxySubject = new ProxySubject();proxySubject.sellBook();//动态代理(通过程序动态生成代理类,该代理类不是我们自己定义的。而是由程序自动生成)RealSubject realSubject = new RealSubject();MyHandler myHandler = new MyHandler();myHandler.setProxySubject(realSubject);Subject subject = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),realSubject.getClass().getInterfaces(), myHandler);subject.sellBook();}
}public class MyHandler implements InvocationHandler {private RealSubject realSubject;public void setProxySubject(RealSubject realSubject) {this.realSubject = realSubject;}/*** @param proxy 指代我们所代理的那个真实对象* @param method 指代的是我们所要调用真实对象的某个方法的Method对象* @param args 指代的是调用真实对象某个方法时接受的参数* @return* @throws Throwable*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {sale();proxy = method.invoke(realSubject, args);give();return proxy;}public void sale() {System.out.println("打折");}public void give() {System.out.println("送优惠券");}
}
享元模式
享元的目的是为了减少不会要额内存消耗,将多个对同一对象的访问集中起来,不必为每个访问者创建一个单独的对象,以此来降低内存的消耗。
public class FlyWeight {static class MyString {private String myChar;public MyString(String myChar) {this.myChar = myChar;}public void display() {System.out.println(myChar);}}static class MyCharacterFactory {private Map<String, MyString> pool;public MyCharacterFactory() {pool = new HashMap<>();}public MyString getMyCharacte(String strig) {MyString myString = pool.get(strig);if (myString == null) {myString = new MyString(strig);pool.put(strig, myString);}return myString;}}public static void main(String[] args) {MyCharacterFactory myCharacterFactory = new MyCharacterFactory();MyString a = myCharacterFactory.getMyCharacte("a");MyString b = myCharacterFactory.getMyCharacte("b");MyString a1 = myCharacterFactory.getMyCharacte("a");MyString d = myCharacterFactory.getMyCharacte("d");if (a == a1) {System.out.println("true");}}
}
相关源码:https://github.com/peiniwan/DesignPattern.git