编写软件过程中,程序员面临着来自耦合性,内聚性以及可维护性,可扩展性,重用性,灵活性 等多方面的挑战,设计模式是为了让程序(软件),具有更好
描述:
对类来说的,即一个类应该只负责一项职责。如类A负责两个不同职责:职责1,职责2。当职责1需求变更而改变A时,可能造成职责2执行错误, 所以需要将类A的粒度分解为A1, A2
目的:
描述:
客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小的接口上
描述:
目的:
描述:
尽量使用合成/聚合的方式,而不是使用继承
Rational Rose
, 也可以使用一些插件来建模Character | Icon for field | Icon for method | Visibility |
---|---|---|---|
- |
![]() |
![]() |
private |
# |
![]() |
![]() |
protected |
~ |
![]() |
![]() |
package private |
+ |
![]() |
![]() |
public |
依赖关系(Dependence)
泛化关系(Generalization)
实现关系(Implementation)
关联关系(Association)
聚合关系(Aggregation)
组合关系(Composition)
描述
所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类
只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法)
class Test{
//本类内部创建静态对象实例
private static final Test test=new Test();
//构造器私有化
private Test(){}
//对外提供公共方法获取静态实例对象
public static Test getInstance(){
return test;
}
}
优缺点说明
class Test{
private static Test test;
//在静态代码块中创建实例
static {
test=new Test();
}
//构造器私有化
private Test(){}
//获取静态实例对象
public static Test getInstance(){
return test;
}
}
class Test {
private static Test test;
//构造器私有化
private Test() {}
//调用getInstance方法时才创建对象
public static Test getInstance() {
if (test == null) {
test = new Test();
}
return test;
}
}
class Test {
private static Test test;
//构造器私有化
private Test() {}
//调用getInstance方法时才创建对象,加入同步代码解决线程同步问题
public static synchronized Test getInstance() {
if (test == null) {
test = new Test();
}
return test;
}
}
class Test {
private static Test test;
//构造器私有化
private Test() {}
public static Test getInstance() {
if (test == null) {
synchronized (Test.class){
test = new Test();
}
}
return test;
}
}
if (test== null)
判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例class Test {
private static volatile Test test;
//构造器私有化
private Test() {}
//双重检查
public static Test getInstance() {
if (test == null) {
synchronized (Test.class){
if (test == null) {
test = new Test();
}
}
}
return test;
}
}
class Test {
//构造器私有化
private Test() {}
public static Test getInstance() {
return TestInstance.TEST;
}
//静态内部类
private static class TestInstance{
private static final Test TEST=new Test();
}
}
enum Test{
INSTANCE;
//设置属性
private Integer id;
public void setId(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void method{
//业务代码
}
}
public class Runtime {
private static Runtime currentRuntime = new Runtime();
/**
* Returns the runtime object associated with the current Java application.
* Most of the methods of class Runtime
are instance
* methods and must be invoked with respect to the current runtime object.
*
* @return the Runtime
object associated with the current
* Java application.
*/
public static Runtime getRuntime() {
return currentRuntime;
}
/** Don't let anyone else instantiate this class */
private Runtime() {}
在jdk的java.lang.Runtime包中使用了饿汉式(静态常量)的单例模式
描述
UML
使用后
//简单工厂类,工厂对象一般是单例
enum SimpleFactory {
INSTENCE;
public AbstractClass getAbstractClass(Integer type){
switch (type){
case 1:
new RealizeClass1();
break;
case 2:
new RealizeClass2();
break;
}
return null;
}
}
//抽象类
abstract class AbstractClass {
public abstract void fun();
}
//实现类1
class RealizeClass1 extends AbstractClass{
@Override
public void fun() {
//RealizeClass1逻辑
}
}
//实现类2
class RealizeClass2 extends AbstractClass{
@Override
public void fun() {
//RealizeClass2逻辑
}
}
优缺点说明
使用了简单工厂模式后可以解除use
和RealizeClass
之间的耦合,可以使得增加新的RealizeClass
时不需要对多个use
进行修改。只需要统一修改唯一的SimpleFactory
即可。
但是当需要不同的SimpleFactory
以提供满足不同需求的对象时,扩展性不够
描述
定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。
UML
/**
* use要使用时在自己类中通过调用对应RealizeFactory对象的create方法来获取对应RealizeClass对象
*/
//抽象工厂方法
abstract class AbstractFactory{
public abstract void create();
}
//生产Class1的工厂实现类
class RealizeFactory1 extends AbstractFactory{
@Override
public void create() {
//用于实现生产RealizeClass1的逻辑
}
}
//生产Class2的工厂实现类
class RealizeFactory2 extends AbstractFactory{
@Override
public void create() {
//用于实现生产RealizeClass2的逻辑
}
}
//抽象类
abstract class AbstractClass {
public abstract void fun();
}
//实现类1
class RealizeClass1 extends AbstractClass{
@Override
public void fun() {
//RealizeClass1逻辑
}
}
//实现类2
class RealizeClass2 extends AbstractClass{
@Override
public void fun() {
//RealizeClass2逻辑
}
}
优缺点说明
使用者只需要找到对应产品的工厂类便能获取到所需的产品对象,并不需要关系产品生产的细节,也便于扩展。当新增产品时只要同时再增加一个对应的工厂类即可,符合开闭原则
但是缺点就是会使得系统复杂度增加。每次增加一个产品就需要增加至少两个类(产品和工厂)
/**
* use要使用时给自己类中InterfaceFactory属性注入对应的实现对象,并调用对象的create方法来获取对应RealizeClass对象
*/
//抽象工厂方法
interface InterfaceFactory{
void create();
}
//生产Class1的工厂实现类
class RealizeFactory1 implements InterfaceFactory{
@Override
public void create() {
//用于实现生产RealizeClass1的逻辑
}
}
//生产Class2的工厂实现类
class RealizeFactory2 implements InterfaceFactory{
@Override
public void create() {
//用于实现生产RealizeClass2的逻辑
}
}
//抽象类
abstract class AbstractClass {
public abstract void fun();
}
//实现类1
class RealizeClass1 extends AbstractClass{
@Override
public void fun() {
//RealizeClass1逻辑
}
}
//实现类2
class RealizeClass2 extends AbstractClass{
@Override
public void fun() {
//RealizeClass2逻辑
}
}
优缺点说明
抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是程序员可以根据创建对象类型使用对应的工厂子类。 这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。
但是工厂簇的扩展将是一件十分费力的事情,假如工厂簇中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的
//Calendar.getInstance()
public static Calendar getInstance()
{
return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
}
private static Calendar createCalendar(TimeZone zone,Locale aLocale)
{
CalendarProvider provider =
LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
.getCalendarProvider();
if (provider != null) {
try {
return provider.getInstance(zone, aLocale);
} catch (IllegalArgumentException iae) {
// fall back to the default instantiation
}
}
Calendar cal = null;
if (aLocale.hasExtensions()) {
String caltype = aLocale.getUnicodeLocaleType("ca");
if (caltype != null) {
switch (caltype) {
case "buddhist":
cal = new BuddhistCalendar(zone, aLocale);
break;
case "japanese":
cal = new JapaneseImperialCalendar(zone, aLocale);
break;
case "gregory":
cal = new GregorianCalendar(zone, aLocale);
break;
}
}
}
if (cal == null) {
// If no known calendar type is explicitly specified,
// perform the traditional way to create a Calendar:
// create a BuddhistCalendar for th_TH locale,
// a JapaneseImperialCalendar for ja_JP_JP locale, or
// a GregorianCalendar for any other locales.
// NOTE: The language, country and variant strings are interned.
if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
cal = new BuddhistCalendar(zone, aLocale);
} else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"
&& aLocale.getCountry() == "JP") {
cal = new JapaneseImperialCalendar(zone, aLocale);
} else {
cal = new GregorianCalendar(zone, aLocale);
}
}
return cal;
}
在jdk的java.util.Calendar包中使用了简单工厂模式
工厂模式小结
//使用类
class Use{
public static void main(String[] args) {
Prototype prototype = new Prototype(1);
try {
//拷贝prototype对象,创建一个属性一样的新对象
Prototype clone = (Prototype)prototype.clone();
Prototype clone1 = (Prototype)prototype.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
//实现Cloneable接口才可以使用clone
class Prototype implements Cloneable{
private Integer id;
public Prototype(Integer id) {
this.id = id;
}
//克隆该实例,使用默认的clone方法来完成
@Override
protected Object clone() throws CloneNotSupportedException {
//可以自定义逻辑
return super.clone();
}
}
<bean id="id01" class="com.atguigu.spring.bean.Monster" scope="prototype"/>
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
//获取monster[通过id获取monster]
Object bean = applicationContext.getBean("id01");
System.out.println("bean" + bean);
@Override
public Object getBean(String name) throws BeansException{
return doGetBean(name,null,null,false);
}
//doGetBean()
protected <T> doGetBean(final String name, ...) throws BeansException{
//省略部分代码
//判断是否为单例模式
if(mbd.isSingleton()){
//省略代码
}
//判断是否为原型模式
else if(mbd.isPrototype()){
Object prototypeInstance = null;
try{
beforePrototypeCreation(beanName);
//createBean返回原型对象
prototypeInstance = createBean(beanName,mbd,args);
}
finally{
afterPrototypeCreation(beanName);
}
//省略代码
}
}
在Spring的IOC实现中使用了原型模式
简单概括:浅拷贝是对象中基本数据类型值传递,引用数据类型引用传递;深拷贝是对象中所有属性值传递。
//通过序列化方式实现深拷贝
class Prototype implements Serializable,Cloneable{
private static final long serialVersionUID = 1L;
//使用默认clone方法是浅拷贝
@Override
protected Object clone() throws CloneNotSupportedException {
//可以自定义逻辑
return super.clone();
}
//深拷贝
public Object deepClone(){
//创建流对象
ObjectOutputStream oos=null;
ObjectInputStream ois=null;
try{
//序列化
oos = new ObjectOutputStream(new ByteArrayOutputStream());
oos.writeObject(this);//当前这个对象以对象流的方式输出
//反序列化
ois=new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
return (Prototype)ois.readObject();
}catch (Exception e){
e.printStackTrace();
return null;
}finally {
//关闭流
}
}
}
//把对象转为json再转回对象,本质是反射
private Object deepCopyByJson(Object obj) {
String json = JSON.toJSONString(obj);
return JSON.parseObject(json, Object.class);
}
//序列化
(New)SerializationUtils.clone(origin);
//抽象建造者
interface Builder{
void buildPartA();
void buildPartB();
void buildPartC();
Object getResult();
}
//产品
class Product{
}
//具体建造者
class ConcreteBuilder implements Builder{
//实现ABC的逻辑
@Override
public void buildPartA() { }
@Override
public void buildPartB() { }
@Override
public void buildPartC() { }
@Override
public Product getResult() {
return new Product();
}
}
//指挥者
class Director{
private Builder builder;
//注入builder
public void setBuilder(Builder builder){
this.builder=builder;
}
public Product getResult(){
//由指挥者确定执行过程返回结果
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
return (Product) builder.getResult();
}
}
优缺点说明
抽象工厂模式VS建造者模式
抽象工厂模式实现对产品家族的创建,一个产品家族是这样的一系列产品:具有不同分类维度的产品组合,采用抽象工厂模式不需要关心构建过程,只关心什么产品由什么工厂生产即可。
而建造者模式则是要求按照指定的蓝图建造产品,它的主要目的是通过组装零配件而产生一个新产品
//StringBuilder是指挥者也是具体建造者
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
/** use serialVersionUID for interoperability */
static final long serialVersionUID = 4383685877147921099L;
//AbstractStringBuilder虽然是抽象类但也是是具体建造者,其中实现类大部分append方法
abstract class AbstractStringBuilder implements Appendable, CharSequence {
//Appendable是抽象建造者
public interface Appendable {
Appendable append(CharSequence csq) throws IOException;
在jdk的java.lang.StringBuilder包中使用了建造者模式
描述
Adapter类,通过继承 BeAdapt类,实现 InterfaceAdapt 接口,完成BeAdapt ->InterfaceAdapt 的适配
UML
//被适配类
class BeAdapt{
public int out220(){
return 220;
}
}
//目标适配接口
interface InterfaceAdapt{
int out5();
}
//适配器类
class Adapter extends BeAdapt implements InterfaceAdapt{
//转换适配
@Override
public int out5() {
return out220()/44;
}
}
//完成适配使用类
class use{
private InterfaceAdapt interfaceAdapt;
//注入InterfaceAdapt实现类对象实例
public void setAdapter(InterfaceAdapt interfaceAdapt){
this.interfaceAdapt=interfaceAdapt;
}
//使用适配方法
public void use(){
interfaceAdapt.out5();
}
}
描述
UML
//被适配类
class BeAdapt{
public int out220(){
return 220;
}
}
//目标适配接口
interface InterfaceAdapt{
int out5();
}
//适配器类
class Adapter implements InterfaceAdapt{
private BeAdapt beAdapt;
//注入BeAdapt对象实例
public void setBeAdapt(BeAdapt beAdapt){
this.beAdapt=beAdapt;
}
//转换适配
@Override
public int out5() {
return beAdapt.out220()/44;
}
}
//完成适配使用类
class use{
private InterfaceAdapt interfaceAdapt;
//注入InterfaceAdapt实现类对象实例
public void setAdapter(InterfaceAdapt interfaceAdapt){
this.interfaceAdapt=interfaceAdapt;
}
//使用适配方法
public void use(){
interfaceAdapt.out5();
}
}
优缺点说明
对象适配器和类适配器其实算是同一种思想,只不过实现方式不同。根据合成复用原则, 使用组合替代继承, 所以它解决了类适配器必须继承BeAdapt的局限性问题,也不再要求InterfaceAdapt必须是接口。使用成本更低,更灵活。
描述
UML
//需要适配的接口
interface Interface{
void fun1();
void fun2();
void fun3();
}
//接口适配抽象类,空方法方式实现接口中所有方法
abstract class AbsAdapter implements Interface{
@Override
public void fun1(){}
@Override
public void fun2(){}
@Override
public void fun3(){}
}
//匿名函数方式实现需要重写的方法
class use{
public void used(){
AbsAdapter absAdapter = new AbsAdapter(){
@Override
public void fun1() {
//根据业务重写fun1
}
};
absAdapter.fun1();
}
}
public class DispatcherServlet extends FrameworkServlet {
// 通过HandlerMapping来映射Controller
mappedHandler = getHandler(processedRequest);
//获取适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
//..
// 通过适配器调用controller的方法并返回ModelAndView
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
}
//DispatcherServlet的getHandlerAdapter方法,根据需要返回适当的HandlerAdapter
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException{
for(HandlerAdapter ha : this.handlerAdapters){
if(logger.isTraceEnabled()){
logger.trace("Testing handler adapter ["+ha+"]");
}
if(ha.supports(handler)){
return ha;
}
}
}
//HandlerAdapter是一个适配器接口,有多个实现类.
//使得每一种Controller有一种对应的适配器实现类,每种Controller有不同的实现方式
public interface HandlerAdapter{
boolean supports(Object handler);
//……
}
在SpringMVC的 HandlerAdapter 中使用了适配器模式
适配器模式在此处代替了if else这种判断。当DispatchServlet获取到不同的request时,可以通过不同的适配器获取不同的Controller的方法进行处理。当需要新增加一个Controller时,只需要增加一个适配器即可。
描述
UML
//桥接类
abstract class Bridge{
private Interface interface1;
//注入Interface实现类的实例对象
public Bridge(Interface interface1){
this.interface1=interface1;
}
protected void fun(){
this.interface1.fun();
}
}
//接口
interface Interface{
void fun();
}
//Bridge的子类1
class RClass1 extends Bridge{
//使用父类构造器
public RClass1(Interface interface1){
super(interface1);
}
@Override
public void fun(){
super.fun();
//子类的逻辑
}
}
//Bridge的子类2
class RClass2 extends Bridge{
//使用父类构造器
public RClass2(Interface interface1){
super(interface1);
}
@Override
public void fun(){
super.fun();
//子类的逻辑
}
}
//接口实现类1
class IClass1 implements Interface{
@Override
public void fun() {
//业务逻辑
}
}
//接口实现类2
class IClass2 implements Interface{
@Override
public void fun() {
//业务逻辑
}
}
//use调用类
class use{
//让RClass和IClass分离,可以自由组合
public static void use1(Bridge bridge){
bridge.fun();
}
public static void main(String[] args) {
//当传入不同Bridge子类对象时可以调用不同的Interface实现类对象方法
use1(new RClass1(new IClass1()));
}
}
//Jdbc 的 java.sql.Driver接口,如果从桥接模式来看,
//Driver就是一个接口,下面可以有MySQL的Driver, Oracle的Driver,这些就可以当做实现接口类
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
public Driver() throws SQLException {
}
static {
try {
//1.注册驱动
//2. 调用DriverManager中的getConnection
//可以通过不同的Driver获取不同的Connection
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
}..
public class DriverManager{
//...
@CallerSensitive
public static Connection getConnection(String url,java.util.Properties info) throws SQLException{
return (getConnection(url,info,Reflection.getCallerClass))
}
}
//java.sql.Connection接口下面还有com.mysql.jdbc.Connection子接口,
//再下面还有MySQLConnection子接口,然后才是实现类
public interface Connection extends Wrapper,AutoCloseabale{
}
在JDBC的通过DriverManager获取Connection源码中使用了桥接模式(变种)
两种模式的区别在于使用场合的不同
描述
装饰者模式:动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(ocp)
UML
//被装饰的对象抽象类
abstract class Component {
public abstract void fun();
}
//被装饰的对象实现类
class ConcreteComponent extends Component {
@Override
public void fun() {
System.out.println("具体对象的操作");
}
}
//装饰抽象类,对被装饰的对象进行装饰
abstract class Decorator extends Component {
private Component component;
//注入被装饰对象
public Decorator(Component component) {
this.component = component;
}
//在被装饰对象上进行装饰
@Override
public void fun() {
this.component.fun();
}
}
//装饰抽象类的子类,在父类基础上进一步进行装饰
class ConcreteDecorator extends Decorator {
//注入被装饰对象
public ConcreteDecorator(Component component) {
super(component);
}
//定义子类自己的装饰方法
private void method() {
System.out.println("method 装饰");
}
//子类装饰过的方法
@Override
public void fun() {
this.method();
super.fun();
}
}
//使用
class use {
public static void main(String[] args) {
Component component = new ConcreteComponent();
//装饰
component = new ConcreteDecorator(component);
//装饰后运行
component.fun();
}
}
public class FilterInputStream extends InputStream {
//被装饰者
protected volatile InputStream in;
//传入InputStream对象
protected FilterInputStream(InputStream in) {
this.in = in;
}
//使用InputStream的read方法
public int read() throws IOException {
return in.read();
}
//使用自己的装饰方法装饰InputStream原本的read(b, off, len)方法
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
public int read(byte b[], int off, int len) throws IOException {
return in.read(b, off, len);
}
jdk的java.io.FilterInputStream就是一个装饰者
//树形结构的抽象类或接口
abstract class Component{
void add(Component component){};
void remove(){
throw new UnsupportedOperationException("不支持的操作");
};
void get(){
throw new UnsupportedOperationException("不支持的操作");
};
void fun(){
//逻辑
}
}
//树枝节点,继承Component,并且重写操作和读取方法
class Composite extends Component{
private List<Component> list=new ArrayList<>();
@Override
void add(Component component) {
list.add(component);
}
@Override
void remove() {
//remove
}
@Override
void get() {
//get
}
}
//叶子节点,继承Component并重写读取方法
class Leaf extends Component{
@Override
void get() {
//get
}
}
//Map接口
public interface Map<K,V> {
//AbstractMap相当于树形结构抽象层
public abstract class AbstractMap<K,V> implements Map<K,V> {
//HashMap相当于树枝节点
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable {
private static final long serialVersionUID = 362498820763181265L;
//重写父类的添加方法
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else {
Node<K,V> e; K k;
if (p.hash == hash &&
//静态内部类Node相当于叶子节点
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
V value;
Node<K,V> next;
Node(int hash, K key, V value, Node<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
在jdk的java.util.HashMap中使用了组合模式
//子系统1
enum ChildSys1{
INSTANCE;
public void sys1fun1(){ }
public void sys1fun2(){ }
public void sys1fun3(){ }
}
//子系统2
enum ChildSys2{
INSTANCE;
public void sys2fun1(){ }
public void sys2fun2(){ }
public void sys2fun3(){ }
}
//子系统3
enum ChildSys3{
INSTANCE;
public void sys3fun1(){ }
public void sys3fun2(){ }
public void sys3fun3(){ }
}
//外观模式类,聚合所有子系统的实例对象然后按照既定流程统一操作
class Facade{
private ChildSys1 sys1;
private ChildSys2 sys2;
private ChildSys3 sys3;
//获取所有子系统对象实例。在Facade构造方法中创建子系统实例是组合方式,也可以用聚合的方式
public Facade(){
this.sys1=ChildSys1.INSTANCE;
this.sys2=ChildSys2.INSTANCE;
this.sys3=ChildSys3.INSTANCE;
}
//流程1
public void fun1(){
sys1.sys1fun1();
sys2.sys2fun1();
sys3.sys3fun1();
}
//流程2
public void fun2(){
sys1.sys1fun2();
sys2.sys2fun2();
sys3.sys3fun2();
}
//流程3
public void fun3(){
sys1.sys1fun3();
sys2.sys2fun3();
sys3.sys3fun3();
}
}
class use{
public static void main(String[] args) {
Facade facade = new Facade();
//统一调用
facade.fun1();
facade.fun2();
facade.fun3();
}
}
public class Configuration {
protected ReflectorFactory reflectorFactory =new DefaultReflectorFactory();
protected ObjectFactory objectFactory =new DefaultObjectFactory();
protected ObjectWrapperFactory objectWrapperFactory =new DefaultObjectWrapperFactory();
public MetaObject newMetaObject(Object object) {
//MetaObject相当于是外观模式聚合object,objectFactory,
//objectWrapperFactory,reflectorFactory等实例
return MetaObject.forObject(object, objectFactory, objectWrapperFactory, reflectorFactory);
}
}
//以聚合的方式获取各个Factory的对象,根据Object的类型选择使用哪个Factory
public class MetaObject{
private MetaObject(Object object, ObjectFactory objectFactory,
ObjectWrapperFactory objectWrapperFactory,ReflectorFactory reflectorFactory){
this.originalObject = object;
this.objectFactory = objectFactory;
this.objectWrapperFactory = objectWrapperFactory;
this.reflectorFactory = reflectorFactory;
if (object instanceof ObjectWrapper) {
this.objectWrapper = (ObjectWrapper) object;
} else if (objectWrapperFactory.hasWrapperFor(object)) {
this.objectWrapper = objectWrapperFacto
} else if (object instanceof Map) {
this.objectWrapper = new MapWrapper(this, (Map) object);
} else if (object instanceof Collection) {
this.objectWrapper = new CollectionWrappe
} else {
this.objectWrapper = new BeanWrapper(this, object);
}
}
MyBatis 中的Configuration 去创建MetaObject 对象使用到外观模式
//需要享元的抽象类,也可以使用接口抽象
//共享内部状态,聚合外部状态
abstract class AbsClass{
abstract void fun(Outside outside);
}
//实现类
class RealClass extends AbsClass{
@Override
void fun(Outside outside) {
outside.out();
//逻辑
}
}
//AbsClass工厂类
class AbsClassFactory{
private static List<AbsClass> list=new ArrayList<>();
//如果有AbsClass对象实例则返回,没有则创建
public static AbsClass getAbsClass(){
if (list.isEmpty()){
list.add(new RealClass());
}
return list.get(0);
}
}
//外部状态
class Outside{
public void out(){}
}
//调用类
class use{
public static void main(String[] args) {
AbsClass absClass = AbsClassFactory.getAbsClass();
absClass.fun(new Outside());
}
}
public final class Integer extends Number implements Comparable<Integer> {
public static Integer valueOf(int i) {
//如果-128<=i<=127之间,则在IntegerCache的缓存中获取值(享元模式返回)
//如果不在此区间,则new一个新的Integer对象
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
在jdk的java.lang.Integer中的valueOf() 方法使用了享元模式
描述
静态代理在使用时,需要定义接口或者父类,被代理对象(即目标对象)与代理对象一起实现相同的接口或者是继承相同父类
UML
//公共接口
interface IProxy{
void fun();
}
//被代理类
class TargetClass implements IProxy{
@Override
public void fun(){
//逻辑
}
}
//代理类,共同实现了IProxy,聚合了IProxy的实现类实例
class ProxyClass implements IProxy{
private IProxy iProxy;
public ProxyClass(IProxy iProxy){
this.iProxy=iProxy;
}
@Override
public void fun(){
//代理的逻辑
iProxy.fun();
}
}
//调用
class use{
public static void main(String[] args) {
//用被代理对象获取静态代理对象,调用代理对象的方法
IProxy proxyClass = new ProxyClass(new TargetClass());
proxyClass.fun();
}
}
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h)
//目标对象实现接口
interface IProxy{
void fun();
}
//被代理类
class TargetClass implements IProxy{
@Override
public void fun(){
//逻辑
}
}
//代理工厂,聚合了IProxy的实现类实例
class ProxyFactory{
private Object target;
public ProxyFactory(Object target){
this.target=target;
}
public Object getProxyInstance(){
//1.ClassLoader loader:指定当前目标对象使用的类加载器,方法固定
//2.Class>[] interfaces:目标对象实现的接口类型,使用泛型方法确认类型
//3.InvocationHandler h:事件处理,会触发事件处理器方法,会把当前执行的目标对象方法作为参数传入
return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//invoke的第一个参数obj:调用方法的对象,一般都是target
//invoke的第二个参数args:方法的参数,一般都是args
//注意:此处不要使用proxy代理对象当方法调用的本体,这样会形成递归死循环
//代理对象逻辑...
Object returnVal = method.invoke(target, args);
//代理对象逻辑...
return returnVal;
}
});
}
}
//调用
class use{
public static void main(String[] args) {
ProxyFactory proxyClass = new ProxyFactory(new TargetClass());
//获取TargetClass的动态代理对象
IProxy proxyInstance =(IProxy)proxyClass.getProxyInstance();
proxyInstance.fun();
}
}
描述
注意事项
UML
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
//被代理类
class TargetClass{
public void fun(){
//逻辑
}
}
//代理工厂,聚合了IProxy的实现类实例
class ProxyFactory implements MethodInterceptor {
private Object target;
public ProxyFactory(Object target){
this.target=target;
}
//返回一个target的代理对象
public Object getProxyInstance(){
//1.创建一个工具类
Enhancer enhancer = new Enhancer();
//2.设置父类
enhancer.setSuperclass(target.getClass());
//3.设置回调函数
enhancer.setCallback(this);
//4.创建子类对象,即代理对象
return enhancer.create();
}
//重写intercept,调用目标对象的方法
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//代理对象逻辑...
Object returnVal = method.invoke(target, objects);
//代理对象逻辑...
return returnVal;
}
}
//调用
class use{
public static void main(String[] args) {
ProxyFactory proxyClass = new ProxyFactory(new TargetClass());
//获取TargetClass的Cglib代理对象
TargetClass proxyInstance =(TargetClass)proxyClass.getProxyInstance();
proxyInstance.fun();
}
}
//模板抽象类,实现了模板template方法,定义了算法骨架,子类实现具体方法fun1,2,3
//模板方法可以定义为final,不让子类重写
abstract class AbsClass{
public final void template(){
fun1();
//通过钩子方法来控制改流程是否执行
if(hook()){
fun3();
}
fun2();
}
//可以是抽象方法也可以是实现的方法
abstract void fun1();
abstract void fun2();
abstract void fun3();
//钩子方法
public boolean hook(){
return true;
}
}
//子类实现模板类中的抽象方法
class RealClass extends AbsClass{
@Override
void fun1() {
//实现逻辑
}
@Override
void fun2() {
//实现逻辑
}
@Override
void fun3() {
//实现逻辑
}
//子类可以根据需求选择是否重写该方法,控制fun2是否执行
@Override
public boolean hook() {
return false;
}
}
//调用模板方法。不同实现类的模板方法结果可能不同,但是大体执行流程是固定的
class use{
public static void main(String[] args) {
AbsClass realClass = new RealClass();
realClass.template();
}
}
//模板接口
public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {
//声明了一个模板方法
void refresh() throws BeansException,IllegalStateException;
}
//实现了模板方法的抽象类
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
//模板方法的实现
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
//该方法在下方执行两个抽象方法
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
this.refreshBeanFactory();
return this.getBeanFactory();
}
//抽象方法
protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;
//抽象方法
public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
//钩子方法
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
//实现抽象模板中的抽象方法
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
//实现抽象方法
protected final void refreshBeanFactory() throws IllegalStateException {
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException("GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
} else {
this.beanFactory.setSerializationId(this.getId());
}
}
//实现抽象方法
public final ConfigurableListableBeanFactory getBeanFactory() {
return this.beanFactory;
}
Spring IOC容器初始化时运用到的模板方法模式
//命令接口,需要执行的命令都在这里,可以是接口或抽象类
interface Command{
//执行操作
void execute();
//撤销操作
void undo();
}
//命令实现类,将一个接受者对象与一个动作绑定,调用接受者相应的操作,实现execute
//一般一个实现类只代表一个操作,比如当前类表示开灯操作
class ConcreteCommand implements Command{
private Receiver receiver;
//注入接受者对象
public ConcreteCommand(Receiver receiver){
this.receiver=receiver;
}
//调用接受者对象的方法完成操作
//对开灯操作execute是on, undo是off
//如果还有一个关灯实现类,则execute是off, undo是on
@Override
public void execute() {
receiver.on();
}
@Override
public void undo() {
receiver.off();
}
}
//空命令对于简化操作有帮助,省去对空的判断
class NoCommand implements Command{
@Override
public void execute() {}
@Override
public void undo() {}
}
//接受者对象,比方说电灯,有打开和关闭
class Receiver{
public void on(){
//打开
}
public void off(){
//关闭
}
}
//调用者对象
class Invoker{
//用一个集合接收命令,此处用数组
private Command[] onCommands=new Command[1];
//撤销命令
private Command undoCommand=new NoCommand();
//初始化开关命令集合为空命令
public Invoker() {
onCommands[0]=new NoCommand();
}
//设置命令方法
public void setOnCommands(int no,Command command){
onCommands[no]=command;
}
//执行方法
public void run(int no){
onCommands[no].execute();
//记录当前的操作对象
undoCommand=onCommands[no];
}
//撤销方法
public void undo(){
undoCommand.undo();
}
}
//使用
class use{
public static void main(String[] args) {
//创建操作对象,把接收者注入
ConcreteCommand concreteCommand = new ConcreteCommand(new Receiver());
Invoker invoker = new Invoker();
//把操作设置到Invoker中
invoker.setOnCommands(0,concreteCommand);
//操作invoker
invoker.run(0);
invoker.undo();
}
}
public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
//jdbcTemplate作为Invoker
public <T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException {
return (List)result(this.query((String)sql, (ResultSetExtractor)(new RowMapperResultSetExtractor(rowMapper))));
}
@Nullable
public <T> T query(final String sql, final ResultSetExtractor<T> rse) throws DataAccessException {
Assert.notNull(sql, "SQL must not be null");
Assert.notNull(rse, "ResultSetExtractor must not be null");
if (this.logger.isDebugEnabled()) {
this.logger.debug("Executing SQL query [" + sql + "]");
}
//此内部类实现了StatementCallback(类似Command),相当于ConcreteCommand,同时也相当于Receiver
//doInStatement被重写,不同的StatementCallback实现类对应着不同的doInStatement方法实现
//jdbcTemplate作为Invoker,execute(StatementCallback action) 调用action.doInStatement 方法
class QueryStatementCallback implements StatementCallback<T>, SqlProvider {
QueryStatementCallback() {
}
@Nullable
public T doInStatement(Statement stmt) throws SQLException {
ResultSet rs = null;
Object var3;
try {
rs = stmt.executeQuery(sql);
var3 = rse.extractData(rs);
} finally {
JdbcUtils.closeResultSet(rs);
}
return var3;
}
public String getSql() {
return sql;
}
}
//execute执行把内部类传入
return this.execute((StatementCallback)(new QueryStatementCallback()));
}
//类似于Command接口
@FunctionalInterface
public interface StatementCallback<T> {
@Nullable
T doInStatement(Statement var1) throws SQLException, DataAccessException;
}
Spring框架的JdbcTemplate就使用到了命令模式
描述
UML
//访问者接口
interface Visitor{
//访问者中要传入ConcreteElement对象
//可以通过传入不同的Element实现对象进行重载
/**
*它定义了对每一个元素(Element)访问的行为,它的参数就是可以访问的元素,
*它的方法个数理论上来讲与元素个数(Element的实现类个数)是一样的,从这点不难看出,
*访问者模式要求元素类的个数不能改变(不能改变的意思是说,如果元素类的个数经常改变,
*则说明不适合使用访问者模式)
*/
void fun(ConcreteElement element);
}
//访问者实现类
class ConcreteVisitor implements Visitor{
@Override
public void fun(ConcreteElement element) {
}
}
//接收接口
interface Element{
//接收一个Visitor对象
void accept(Visitor visitor);
}
//接收实现类
//双分派:
// 1.在use中把Visitor作为参数传递到ConcreteElement中(第一次分派)
// 2.然后ConcreteElement调用作为参数的Visitor中的fun方法,同时将自己(this)对象作为参数传入(第二次分派)
class ConcreteElement implements Element{
@Override
public void accept(Visitor visitor) {
//Visitor中需要传入具体实现类是因为可以通过不同的Element实现对象调用不同的方法
visitor.fun(this);
}
}
//数据结构,管理双方对象,用来允许访问者访问元素
class ObjectStruture{
//维护一个集合
private List<Element> elementList=new LinkedList<>();
//添加
public void add(Element element){
elementList.add(element);
}
//移除
public void remove(Element element){
elementList.remove(element);
}
//显示当前visitor和所有element的情况
public void show(Visitor visitor){
for (Element element : elementList) {
element.accept(visitor);
}
}
}
//调用
class use{
public static void main(String[] args) {
//先创建ObjectStruture对象
ObjectStruture objectStruture = new ObjectStruture();
//往ObjectStruture中添加ConcreteElement对象
objectStruture.add(new ConcreteElement());
//获取ConcreteVisitor访问的结果
objectStruture.show(new ConcreteVisitor());
}
}
//元素类
class Element{
private int id;
public Element(int id){
this.id=id;
}
public int getId(){
return id;
}
}
//Iterator实现类,Iterator是系统接口。
class ConcreteIterator implements Iterator<Element>{
//这里需要知道Element是以什么形式存放的
private Element[] elements;
int position=0;//遍历位置
public ConcreteIterator(Element[] elements) {
this.elements = elements;
}
//判断是否还有下一个
@Override
public boolean hasNext() {
if(elements[position]==null || position>=elements.length){
return false;
}
return true;
}
//获取下一个Element
@Override
public Element next() {
Element element=null;
if (elements!=null && position<elements.length){
element = elements[this.position++];
}
return element;
}
}
//元素集合抽象类
interface AbsClass{
Iterator getIterator();
}
//元素集合实现类
class ConcreteClass implements AbsClass{
private Element[] elements=new Element[3];
public ConcreteClass(){
elements[0]=new Element(1);
elements[0]=new Element(2);
elements[0]=new Element(3);
}
@Override
public Iterator<Element> getIterator() {
//根据不同的集合存储数据的方式,创建不同的ConcreteIterator来遍历
return new ConcreteIterator(elements);
}
}
//调用
class use{
public static void main(String[] args) {
ConcreteClass concreteClass = new ConcreteClass();
Iterator<Element> iterator = concreteClass.getIterator();
while (iterator.hasNext()){
Element element = iterator.next();
element.getId();
}
}
}
//ArrayList实现List接口,List相当于AbsClass,ArrayList相当于ConcreteClass
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
//相当于getIterator方法,获取Iterator对象
public Iterator<E> iterator() {
return new Itr();
}
//用内部类实现Iterator接口,相当于ConcreteIterator,
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
Itr() {}
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
//因为Itr是内部类,所以直接使用elementData
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
@Override
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer) {
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
JDK的ArrayList 集合中就使用了迭代器模式
描述
观察者模式:对象之间多对一依赖的一种设计方案,被依赖的对象为Subject,依赖的对象为Observer, Subject通知Observer变化。Subject是1的一方,Observer是多的一方
UML
//依赖对象接口
interface Subject{
void register(Observer obs);
void remove(Observer obs);
void notifyOb();
}
//依赖对象实现类
class ConceteSubject implements Subject{
private int param;
private List<Observer> list;
public void setParam(int param){
this.param=param;
//当内容有变化时推送给所有观察者
notifyOb();
}
public ConceteSubject() {
this.list=new ArrayList<>();
}
@Override
public void register(Observer obs) {
list.add(obs);
}
@Override
public void remove(Observer obs) {
list.remove(obs);
}
//通知所有观察者
@Override
public void notifyOb() {
for (Observer observer : list) {
observer.update(param);
}
}
}
//观察者接口
interface Observer{
void update(int param);
}
//观察者实现类
class ConceteObserver implements Observer{
private int param;
@Override
public void update(int param) {
this.param=param;
}
public int getParam(){
return param;
}
}
//调用
class use{
public static void main(String[] args) {
//创建一个依赖对象
ConceteSubject conceteSubject = new ConceteSubject();
//创建观察者对象
ConceteObserver conceteObserver1 = new ConceteObserver();
ConceteObserver conceteObserver2 = new ConceteObserver();
//注册观察者对象
conceteSubject.register(conceteObserver1);
conceteSubject.register(conceteObserver2);
//更新依赖对象中元素的时候就会实时更新所有观察者的元素
conceteSubject.setParam(1);
}
}
//Observable没有抽象成接口,直接本类完成了Subject的功能
public class Observable {
private boolean changed = false;
private Vector<Observer> obs; //用于接收Observer的集合
public Observable() {
obs = new Vector<>();
}
//注册Observer
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!obs.contains(o)) {
obs.addElement(o);
}
}
//删除Observer
public synchronized void deleteObserver(Observer o) {
obs.removeElement(o);
}
//通知Observer
public void notifyObservers() {
notifyObservers(null);
}
//通知Observer
public void notifyObservers(Object arg) {
Object[] arrLocal;
//用同步代码块线程安全的判断数据是否有更新,如果有则通知,并且清除更新标记
synchronized (this) {
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
}
for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
}
public synchronized void deleteObservers() {
obs.removeAllElements();
}
protected synchronized void setChanged() {
changed = true;
}
protected synchronized void clearChanged() {
changed = false;
}
public synchronized boolean hasChanged() {
return changed;
}
public synchronized int countObservers() {
return obs.size();
}
}
Jdk的java.util.Observable类就使用了观察者模式
//中介抽象类
abstract class Mediator{
//维护所有同事对象的集合
protected Map<String,Colleague> map;
public Mediator() {
this.map=new HashMap<>();
}
//把同事类添加到map中
public abstract void register(String name,Colleague colleague);
//接收同事实现类发出的消息
public abstract void getMessage(int stataChange, String name);
public abstract void sendMessage();
}
//中介实现类
class ConcreteMediator extends Mediator{
@Override
public void register(String name, Colleague colleague) {
map.put(name,colleague);
}
//中介者核心方法
@Override
public void getMessage(int stataChange, String name) {
Colleague colleague=null;
//根据得到的消息完成对应任务
//中介者在这个方法中协调各个具体的同事对象完成任务
switch (stataChange){
case 0:
colleague = map.get(name);
break;
case 1:
colleague = map.get(name+1);
break;
case 2:
colleague = map.get(name+2);
break;
default:
colleague = null;
}
}
@Override
public void sendMessage() {
}
}
//同事抽象类
abstract class Colleague{
private Mediator mediator;
protected String name;
public Colleague(Mediator mediator, String name) {
this.mediator = mediator;
this.name = name;
}
public Mediator getMediator() {
return this.mediator;
}
public abstract void sendMessage(int stateChange);
}
//同事实现类
class ConcreteColleague1 extends Colleague{
public ConcreteColleague1(Mediator mediator, String name) {
super(mediator, name);
//创建对象时将自己放到Mediator实现类对象中
mediator.register(name, this);
}
//给中介者发送消息
@Override
public void sendMessage(int stateChange) {
this.getMediator().getMessage(stateChange, this.name);
}
}
//同事实现类
class ConcreteColleague2 extends Colleague{
public ConcreteColleague2(Mediator mediator, String name) {
super(mediator, name);
//创建对象时将自己放到Mediator实现类对象中
mediator.register(name, this);
}
//给中介者发送消息
@Override
public void sendMessage(int stateChange) {
this.getMediator().getMessage(stateChange, this.name);
}
}
//调用
class use{
public static void main(String[] args) {
//创建中介者对象
Mediator mediator = new ConcreteMediator();
//创建同事对象并通过构造器把自己注册到中介对象中
ConcreteColleague1 colleague1 = new ConcreteColleague1(mediator, "Colleague1");
ConcreteColleague2 colleague2 = new ConcreteColleague2(mediator, "Colleague2");
//给中介对象发送消息0,中介对象会按照0号方案预设的流程去处理colleague1对象
colleague1.sendMessage(0);
}
}
//原始信息类
class Origin{
//状态信息
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
//保存。返回保存对象
public Memery save(){
return new Memery(this.state);
}
//获取保存对象恢复状态信息
public void get(Memery memery){
this.state=memery.getState();
}
}
//保存对象
class Memery{
//状态信息
private String state;
public Memery(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
//保存对象管理类
class Caretaker{
//集合维护保存对象
private List<Memery> list=new ArrayList<>();
//添加保存对象到集合中管理
public void add(Memery memery){
list.add(memery);
}
//获取第index个保存对象
public Memery get(int index){
return list.get(index);
}
}
//调用
class use{
public static void main(String[] args) {
//获取原始信息类和保存对象管理类对象
Origin origin = new Origin();
Caretaker caretaker = new Caretaker();
//设置原始状态为100
origin.setState("100");
//保存状态
caretaker.add(origin.save());
//设置原始状态为80
origin.setState("80");
//把原始状态恢复为100
origin.get(caretaker.get(0));
}
}
//抽象表达式, 声明一个抽象的解释操作,这个方法为抽象语法树中所有的节点所共享
abstract class AbsExpression{
//解释表达式计算数值
public abstract int interpret(Map<String,Integer> map);
}
//为终结符表达式, 实现与文法中的终结符相关的解释操作
//变量解释器
class TerminalExpression extends AbsExpression{
private String key;
public TerminalExpression(String key) {
this.key = key;
}
//根据变量名称返回对应值
@Override
public int interpret(Map<String, Integer> map) {
return map.get(key);
}
}
//为非终结符表达式,为文法中的非终结符实现解释操作
//运算符解释器
class NonTerminalExpression extends AbsExpression{
//每个运算符都只和自己左右两个数字有关系,但左右两个数字有可能也是一个解释结果。无论何种类型,都是AbsExpression的实现类
protected AbsExpression left;
protected AbsExpression right;
public NonTerminalExpression(AbsExpression left, AbsExpression right) {
this.left = left;
this.right = right;
}
//这个可以让其子类来实现,目前只需要一个默认实现(例如:加减乘除运算符,分别在子类实现)
@Override
public int interpret(Map<String, Integer> map) {
return 0;
}
}
//运算符解释器子类实现,加法解释器
class AddExpression extends NonTerminalExpression{
//调用父类构造初始化,把左边的值和右边的值初始
public AddExpression(AbsExpression left, AbsExpression right) {
super(left, right);
}
//由于left和right都是TerminalExpression,所以interpret会取出对应表达式的值
@Override
public int interpret(Map<String, Integer> map) {
return super.left.interpret(map)+super.right.interpret(map);
}
}
//表达式解析类
//环境角色,含有解释器之外的全局信息
class Context {
//定义表达式
private AbsExpression absExpression;
public Context(String expStr){ //a+b
//创建一个栈安排运算先后顺序
Stack<AbsExpression> stack=new Stack<>();
//表达式拆分成字符数组
char[] charArray=expStr.toCharArray();//[a,+,b]
AbsExpression left=null;
AbsExpression right=null;
// 遍历字符数组
//针对不同运算符分别处理
for (int i = 0; i < charArray.length; i++) {
switch (charArray[i]){
case '+':
//如果对象是一个运算符,则从栈中取出最左边(第一个)元素为left,再从数组中取出下一个元素为right
//把他们包装成AddExpression并压入stack中
left=stack.pop(); //从栈中取出left
right=new TerminalExpression(String.valueOf(charArray[++i]));//i+1,从数组中取出下一个元素right
stack.push(new AddExpression(left, right));//根据得到的left和right创建AddExpression并压入栈中
break;
default:
//如果字符是一个元素,则包装成一个TerminalExpression对象并push到stack
stack.push(new TerminalExpression(String.valueOf(charArray[i])));
break;
}
}
//当遍历完整个charArray数组后,从stack就得到最后的AddExpression存入absExpression属性中
this.absExpression=stack.pop();
}
public int run(Map<String,Integer> map){
//absExpression里是AddExpression对象,所以执行AddExpression的interpret方法,把left和right对应的值取出来相加
return this.absExpression.interpret(map);
}
}
//调用
class use{
public static void main(String[] args) throws IOException {
String expStr=getExpStr(); //a+b
Map<String, Integer> map=getValue(expStr);//map {a=10,b=20}
Context context =new Context(expStr);
System.out.println("结果:"+expStr + "="+ context.run(map));
}
//开启键盘输入,获得表达式
public static String getExpStr() throws IOException{
System.out.println("输入表达式");
return (new BufferedReader(new InputStreamReader(System.in))).readLine();
}
//获得值映射
public static Map<String, Integer> getValue(String expStr) throws IOException{
Map<String, Integer> map=new HashMap<>();
for (char ch : expStr.toCharArray()) {
if (ch != '+'){
if (!map.containsKey(String.valueOf(ch))) {
System.out.print("请输入" + String.valueOf(ch) + "的值:");
//分别输入key=a和key=b的值,并把键值对保存在map中
String in = (new BufferedReader(new InputStreamReader(System.in))).readLine();
map.put(String.valueOf(ch), Integer.valueOf(in));
}
}
}
return map;
}
}
//相当于AbsExpression抽象类
public interface ExpressionParser {
Expression parseExpression(String var1) throws ParseException;
Expression parseExpression(String var1, ParserContext var2) throws ParseException;
}
public abstract class TemplateAwareExpressionParser implements ExpressionParser {
public TemplateAwareExpressionParser() {
}
public Expression parseExpression(String expressionString) throws ParseException {
return this.parseExpression(expressionString, (ParserContext)null);
}
//根据传入的表达式不同返回不同的Expression对象
private Expression parseTemplate(String expressionString, ParserContext context) throws ParseException {
if (expressionString.isEmpty()) {
return new LiteralExpression("");
} else {
Expression[] expressions = this.parseExpressions(expressionString, context);
return (Expression)(expressions.length == 1 ? expressions[0] : new CompositeStringExpression(expressionString, expressions));
}
}
//相当于Context,使用时先获取SpelExpressionParser对象,然后调用TemplateAwareExpressionParser中实现的
//parseExpression方法,传入一个表达式字符串,包装成表达式对象并解释执行,parseExpression相当于run
public class SpelExpressionParser extends TemplateAwareExpressionParser {
private final SpelParserConfiguration configuration;
public SpelExpressionParser() {
this.configuration = new SpelParserConfiguration();
}
public SpelExpressionParser(SpelParserConfiguration configuration) {
Assert.notNull(configuration, "SpelParserConfiguration must not be null");
this.configuration = configuration;
}
public SpelExpression parseRaw(String expressionString) throws ParseException {
return this.doParseExpression(expressionString, (ParserContext)null);
}
protected SpelExpression doParseExpression(String expressionString, @Nullable ParserContext context) throws ParseException {
return (new InternalSpelExpressionParser(this.configuration)).doParseExpression(expressionString, context);
}
}
Spring框架中 org.springframework.expression.spel.standard.SpelExpressionParser就使用到解释器模式
//状态抽象类
abstract class State{
public abstract void fun();
}
//状态子类A,代表其中一种状态
class ConcreteStateA extends State{
private Context context;
public ConcreteStateA() {
}
//注入Context对象
public ConcreteStateA(Context context) {
this.context = context;
}
@Override
public void fun() {
//在状态对象的行为方法中改变状态
context.setState(new ConcreteStateB());
}
}
//状态子类B,代表其中一种状态
class ConcreteStateB extends State{
private Context context;
public ConcreteStateB() {
}
public ConcreteStateB(Context context) {
this.context = context;
}
@Override
public void fun() {
context.setState(new ConcreteStateA());
}
}
//状态上下文对象
class Context{
private State state;
//持有所有状态子类对象,把自己对象传入
State stateA=new ConcreteStateA(this);
State stateB=new ConcreteStateB(this);
//初始化设置默认状态
public Context() {
this.state = stateA;
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
//外部使用上下文对象的行为方法时,调用当前状态对象的行为方法
public void fun(){
state.fun();
}
}
//调用
class use{
public static void main(String[] args) {
Context context = new Context();
context.fun();
}
}
//策略接口,代码模块中需要动态配置的部分抽取
interface Interface{
void fun();
}
//策略接口实现类A,代表策略的一种
class ConcreteInterfaceA implements Interface{
@Override
public void fun() {
//该策略逻辑
}
}
//策略接口实现类B,代表策略的一种
class ConcreteInterfaceB implements Interface{
@Override
public void fun() {
//该策略逻辑
}
}
//抽象整合类。代码模块中共用的部分
abstract class Context{
protected Interface interface1;
public void fun(){
//父类默认实现方法
}
}
//整合实现类
class ConcreteContext extends Context{
public ConcreteContext() {
//在构造器中可以动态的指定使用策略A还是策略B,把以前放在父类中的代码抽取出来以聚合或
//组合的方式动态的配置给其他类
interface1=new ConcreteInterfaceA();
}
//子类自己的方法调用父类方法和策略对象方法
public void fun1(){
super.fun();
interface1.fun();
}
}
//调用
class use{
public static void main(String[] args) {
ConcreteContext concreteContext = new ConcreteContext();
concreteContext.fun1();
}
}
//相当于Interface策略接口。
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
//当使用时,实现Comparator接口的对象就是策略实现对象
Comparator comparator= new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return 0;
}
@Override
public boolean equals(Object obj) {
return false;
}
};
//Arrays相当于Context整合类
Arrays.sort(new Integer[]{1,2,3}, comparator);
//Arrays相当于Context整合类。通过改变策略实现类来实现排序的方式
public class Arrays {
public static <T> void sort(T[] a, Comparator<? super T> c) {
if (c == null) {
sort(a);
} else {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, c);
else
TimSort.sort(a, 0, a.length, c, null, 0, 0);
}
}
JDK的 Arrays 的 java.util.Comparator 就使用了策略模式
//请求对象
class Request{
private int param1;
private int param2;
public Request(int param1, int param2) {
this.param1 = param1;
this.param2 = param2;
}
public int getParam1() {
return param1;
}
public int getParam2() {
return param2;
}
}
//抽象的处理者, 定义了一个处理请求的接口, 同时含义另外Handler
abstract class Handler{
protected Handler handler;
private String name;
public Handler(String name) {
this.name = name;
}
//设置下一个处理着
public void setHandler(Handler handler) {
this.handler = handler;
}
//处理请求的方法,子类实现
public abstract void processRequest(Request request);
}
//具体的处理者A, 处理它自己负责的请求, 可以访问它的后继者(即下一个处
//理者), 如果可以处理当前请求,则处理,否则就将该请求交个 后继者去处理,从而形成一个职责链
class ConcreteHandlerA extends Handler{
public ConcreteHandlerA(String name) {
super(name);
}
@Override
public void processRequest(Request request) {
if(request.getParam1()<0){
//处理逻辑
}else{
//调用下一个handler的处理方法去处理
if (handler != null) {
handler.processRequest(request);
}else{
//默认处理
}
}
}
}
//具体处理者B
class ConcreteHandlerB extends Handler{
public ConcreteHandlerB(String name) {
super(name);
}
@Override
public void processRequest(Request request) {
if(request.getParam1()==0){
//处理逻辑
}else{
//调用下一个handler的处理方法去处理
if (handler != null) {
handler.processRequest(request);
}else{
//默认处理
}
}
}
}
//调用
class use{
public static void main(String[] args) {
Request request = new Request(1, 2);
ConcreteHandlerA handlerA = new ConcreteHandlerA("HandlerA");
ConcreteHandlerA handlerB = new ConcreteHandlerA("HandlerB");
//设置责任关系
handlerA.setHandler(handlerB);
//如果没人能处理则默认处理
handlerA.processRequest(request);
}
}
public class DispatcherServlet extends FrameworkServlet {
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
//HandlerExecutionChain 主要负责的是请求拦截器的执行和请求处理,但是他本身不
//处理请求,只是将请求分配给链上注册处理器执行, 这是职责链实现方式,减少职责
//链本身与处理逻辑之间的耦合,规范了处理流程
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Object dispatchException = null;
try {
processedRequest = this.checkMultipart(request);
multipartRequestParsed = processedRequest != request;
//获取到HandlerExecutionChain对象
mappedHandler = this.getHandler(processedRequest);
//...
//调用了HandlerExecutionChain中的applyPreHandle方法
//在applyPreHandle内部得到了HandlerInterceptor拦截器,并调用了它的preHandle方法
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
//...
//如果上面applyPreHandle()调用处理失败则返回,成功则接着执行applyPostHandle方法
//形成责任链
mappedHandler.applyPostHandle(processedRequest, response, mv);
public class HandlerExecutionChain {
private static final Log logger = LogFactory.getLog(HandlerExecutionChain.class);
private final Object handler;
@Nullable
//HandlerExecutionChain 维护了 HandlerInterceptor 的集合, 可以向其中注册相应的拦截器
private HandlerInterceptor[] interceptors;
@Nullable
private List<HandlerInterceptor> interceptorList;
private int interceptorIndex;
void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) throws Exception {
HandlerInterceptor[] interceptors = this.getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for(int i = this.interceptorIndex; i >= 0; --i) {
HandlerInterceptor interceptor = interceptors[i];
try {
//此处调用了拦截器的afterCompletion方法
interceptor.afterCompletion(request, response, this.handler, ex);
} catch (Throwable var8) {
logger.error("HandlerInterceptor.afterCompletion threw exception", var8);
}
}
}
SpringMVC-HandlerExecutionChain 类就使用到职责链模式