Xchart 源码分析(1)
学校课程需要找一份代码,来讲讲代码里面用了哪些设计模式- -! 还是要java的。。。 于是上github上面翻代码,偶然翻到一个java的xchart图标库,感觉可能以后会用的到,而且代码不是很长,就直接拿过来用了。具体的链接地址如下:https://github.com/timmolter/XChart
一共有6个包,最后一个是用来测试的包,可以忽略不计,一共5个包,5个包的作用分别是
学校课程需要找一份代码,来讲讲代码里面用了哪些设计模式- -! 还是要java的。。。 于是上github上面翻代码,偶然翻到一个java的xchart图标库,感觉可能以后会用的到,而且代码不是很长,就直接拿过来用了。具体的链接地址如下:https://github.com/timmolter/XChart
一共有6个包,最后一个是用来测试的包,可以忽略不计,一共5个包,5个包的作用分别是
在实际开发的时候,我们同样的一个对象,对于不同的客户,可能能够调用的方法是不一样的,就是权限的控制,这个时候,对象的方法都应该是public,那么就要给对象加上一层,通过客户的类型,决定是否可以访问,也就是说,客户不直接访问对象,而是访问给对象加上的这一层,就是代理层。
1 | public interface T1{ |
这样就可以在代理类中,控制对象的访问了,当然代理模式实现方式还有很多种,(远程代理管理客户和远程对象的交互,虚拟代理控制访问实例化开销大的对象,保护代理基于调用者控制对对象方法的访问),上面只是其中的一种方式,代理模式的定义如下:
状态模式是针对系统的状态转换的,其主要的定义如下:
1 | 状态模式:允许对象在内部状态改变时改变他的行为,对象看起来好像修改了它的类。 |
为了方便状态转移 我们为状态定义一个通用的接口,然后每一种状态都实现这个接口,而在系统类中,通过构造函数,将系统本身传入状态类中,这样,每一种状态的改变,都可以在自己类的内部完成,同时提高了可扩展性:
1 | public interface State{ |
虽然在实现上 状态模式和策略模式以及模板方法有些相似 但是几个设计模式完全不一样,策略模式是将可以互换的行为封装起来,然后使用委托的方法决定使用哪一个行为,模板方法则是由子类决定具体的如何实现算法中的某些步骤,而算法的流程是给定的,而状态模式则封装的是基于状态的行为,并将行为委托到当前状态,由当前状态来决定具体行为。
1.迭代器模式完成的功能是和迭代器一样的,封装了对对象的顺序遍历,因为子类的对象集合的存储方式可能并不一致。但是存储的对象是一致的。
1 | public classItem{ |
通过这种方法,我们就可以通过自己定义的一个迭代器来访问数组,同时通过createIterator的方法来顺序遍历存储结构不一样的Set1和Set2中item对象。所以迭代器模式就是:
1 | 迭代器模式:提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露其内部的表示。 |
2.组合模式
组合模式其实就是整体与部分的一个关系,其实就是一个树形结构,根节点由他的子节点组合而成,而子节点又有自己的子节点来组合而成,所以组合模式的定义如下:
前面学习过了策略模式,策略模式是对一类的算法进行封装,利用组合,算法之间可以互相替换,但是这个是针对算法过程不是一样的算法。但是如果一系列的算法的步骤都是一样的,且算法的很多过程都是一样的处理,那么,用策略模式的话,会导致算法的重用不高,我们采用模板方法来实现:
1 | 模板方法模式:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。 |
1 | public abstract class CAL{ |
其中模板类是一个抽象类,其中算法是确定了的,A1,A2是公共的方法,所有的子类都是一样的,A3,A4是子类自己实现的不一样的函数,定义为抽象方法,子类实现,而Judge方法被成为钩子,默认返回true,而子类可以重写这个方法,这样就能让子类拥有自己的方法。但是这个也反应了模板方法的一个缺点,就是与策略模式相比,弹性不足。
1.适配器模式
适配器模式是针对接口不一时处理的情况,比如我的类的参数是IInterface1,但是我现在想要调用IInterface2接口的函数,怎么办呢?就是用适配器来解决这个问题:
1 | public interface IInterface1(){ |
现在我们调用IIterface2的method1的方法的时候,就是可以直接构造一个适配器来完成
1 | public class A{ |
其中claimplementInterface2是实现Interface2的一个类的实例。这种适配器的方法被称作为对象适配器,还有一种适配器,叫做类适配器,是基于类的多继承的,其中适配器继承自要适配的两个类,用其中一个类的方法调用另一个类,思想是一致的,不过java不支持多继承,所以也就是只能用对象适配器。
命令模式这个设计模式更像是对接口编程的一种应用,比如给小朋友穿衣服,但是不一样的衣服有不一样的穿法,裤子,衬衫,鞋,T恤都是不一样的,但是小朋友不知道怎么穿,只知道想穿什么,那么怎么办呢,小朋友会让他的妈妈帮他穿,这里面的“让妈妈帮忙”,就是给妈妈一个命令(虽然不是很恰当- -!),对小朋友而言,怎么穿他并不关心,反正只要有只要让妈妈穿就行了,所以我们只要定义一个穿的接口就行
1 | public interface Wear() |
然后继承这个穿,有很多种执行方式,比如穿鞋,穿衬衫,穿裤子
1 | public class WearShoe implements Wear{ |
工程中,某些对象我们只需要一个,比如线程池,缓存,对话框等的对象,我们通常的做法是可以定一个全局静态变量,然后通过程序初始化的时候就实例化他们,然后直接调用这个全局变量,但是这样有个问题,如果我的这个对象消耗的资源很多,而有的时候,我的程序在运行过程中又没用到这个对象,岂不是浪费了很多资源。通常的做法就是定义全局静态变量的时候,不初始化他,而是在调用过程中实例化,这样的话,对于全局变量的实例化,我们就要判断这个变量是否已经实例化了,如果实例化了的吧,我们就不对它进行实例化,所以代码如下:
在面向对象的编程中,我们常常会用到new这个关键字,同时,面向对象可以实现多态,这样的话,我们常常就会用父类或者接口定义一个变量,在用到这个变量的时候,再new一个具体的对象,但是有的时候,这个new的对象不是确定的,可能是要根据不同的场景,new出不同的子类,这个很简单的就可以通过if 或者switch来判断实现,但是,这样子以来的话,如果在很多个地方都出现了这种情况,岂不是都要在这些个地方来写这些一样的代码?这样真的好么?
工厂模式就是用来解决这种对象的生成的办法。工厂模式主要分为3种:简单工厂,工厂方法,抽象工厂。
这一章看完之后,我感觉,装饰者模式就是对类继承的一种递归调用式的组合应用,很好的是实现了开闭原则,可以有效的扩展应用程序。比如书中的例子,有几种饮料,每种饮料的价格已经知道了,但是我们又有很多种的调料,每种调料也有它的价格,我们现在需要是在饮料中加调料,那么这样一来,饮料的售价就会变化,如何来描述这种售价呢?如果通过对调料种类的组合来定义若干的类,肯定是非常愚蠢的行为。
通过装饰者模式,就能很好的解决这个问题,我们将这些类分为装饰类(调料),待装饰类(饮料)两种,这两种类继承同一个父类,不同的是装饰类中的构造函数有一个父类引用的构造函数,这样子就可以递归调用构造函数来进行 装饰了。
1
2
3
4
5
6
7
8
9
10
11
12 public class A extends BaseClass{
public string who()
{
return "A";
}
public int cost()
{
return 5;
}
}我们定义一个待装饰类A,再定义几个装饰类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 public class decorator1 extends BaseClass{
BaseClass baseClass;
public decorator1(BaseClass t)
{
this.baseClass = t;
}
public string who()
{
return baseClass.who()+",decoratro1";
}
public int cost()
{
return baseClass.cost()+10;
}
}
public class decorator2 extends BaseClass{
BaseClass baseClass;
public decorator2(BaseClass t)
{
this.baseClass = t;
}
public string who()
{
return baseClass.who()+",decoratro2";
}
public int cost()
{
return baseClass.cost()+20;
}
}然后我们在用decorator1 和decorator2 来装饰A的时候,就有了很犀利的调用方法:
1
2
3
4
5 A a;
a=new decorator1(a);
a=new deocorator2(a);
system.out.println(a.who());
system.out.println(a.cost());这样子 输出就是
1
2 A,decorator1,decorator2
35实际的调用过程就是一个递归的过程。
装饰者模式的定义:
1 装饰者模式:动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更具有弹性的替代方案其中用到的设计原则:
1 开闭原则:对扩展开放,对修改关闭