设计模式
23种设计模式,一个没少。比较常用的:单例、工厂、适配器、装饰者、代理、观察者这几个模式。其他的做了解。
创建型模式
单例模式
作用:确保一个类只有一个实例,只对外提供一个访问该实例的全局访问点。
特征:
1、无法通过new得到实例,构造器是被private修饰的
2、一般通过getInstance()的方法来获取它们的实例,而getInstance方法是对象的引用,并不是真正的new一个对象
对于单例模式,又分为这几类
饿汉式单例模式
我的理解就是饿汉就是初始化就对对象加载,没有延时
public class SingletonDemo1 {
<span class="token comment">//类初始化时,立即加载这个对象(没有延时加载的优势)。加载类时,天然的是线程安全的!</span>
<span class="token keyword">private</span> <span class="token keyword">static</span> SingletonDemo1 instance <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SingletonDemo1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token function">SingletonDemo1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token punctuation">}</span>
<span class="token comment">//方法没有同步,调用效率高!</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> SingletonDemo1 <span class="token function">getInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">return</span> instance<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
懒汉式加载(线程不安全)
public class Singleton {
private static Singleton singleton;
private Singleton() {
}
public static Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
懒汉式加载(线程安全)
public class SingletonDemo2 {
<span class="token comment">//类初始化时,不初始化这个对象(延时加载,真正用的时候再创建)。</span>
<span class="token keyword">private</span> <span class="token keyword">static</span> SingletonDemo2 instance<span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token function">SingletonDemo2</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment">//私有化构造器</span>
<span class="token punctuation">}</span>
<span class="token comment">//方法同步,调用效率低!</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">synchronized</span> SingletonDemo2 <span class="token function">getInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>instance<span class="token operator">==</span>null<span class="token punctuation">)</span><span class="token punctuation">{</span>
instance <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SingletonDemo2</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> instance<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
双重检查锁
注意:
双重检测锁式:涉及到JVM底层内部模型,偶尔会出问题。不建议使用
public class SingletonDemo3 {
private static SingletonDemo3 instance = null;
public static SingletonDemo3 getInstance() {
if (instance null) {
SingletonDemo3 sc;
synchronized (SingletonDemo3.class) {
sc = instance;
if (sc null) {
synchronized (SingletonDemo3.class) {
if(sc == null) {
sc = new SingletonDemo3();
}
}
instance = sc;
}
}
}
return instance;
}
private SingletonDemo3() {
}
}
静态内部类
这个方法需要熟悉使用,很多用到单例的地方用这个方法就差不多可以了,优点:线程安全,调用效率高,并且实现了延时加载!
public class SingletonDemo4 {
<span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">SingletonClassInstance</span> <span class="token punctuation">{</span>
<span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> SingletonDemo4 instance <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SingletonDemo4</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">private</span> <span class="token function">SingletonDemo4</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token punctuation">}</span>
<span class="token comment">//方法没有同步,调用效率高!</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> SingletonDemo4 <span class="token function">getInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">return</span> SingletonClassInstance<span class="token punctuation">.</span>instance<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
枚举实现单例模式
这个方法也很好地避免了多线程同步的问题,并且还能够反序列化重新创建对象。
public enum SingletonDemo5 {
<span class="token comment">//这个枚举元素,本身就是单例对象!</span>
INSTANCE<span class="token punctuation">;</span>
}
实际上,这里的单例模式并不是真正的单例,当出现反射和反序列化的时候就会变成原来的普通对象
反射测试
//懒汉测试类
public class SingletonDemo06 /*implements Serializable*/{
<span class="token keyword">private</span> <span class="token keyword">static</span> SingletonDemo06 instace<span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token function">SingletonDemo06</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//需要私有化构造器</span>
<span class="token punctuation">}</span>
<span class="token comment">//方法需要同步,调用效率低</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">synchronized</span> SingletonDemo06 <span class="token function">getInstace</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>null <span class="token operator">==</span> instace<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
instace <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SingletonDemo06</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> instace<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
通过反射调用私有构造器
public static void main(String[] args) throws Exception, SecurityException {
SingletonDemo06 s1 = SingletonDemo06.getInstace();
SingletonDemo06 s2 = SingletonDemo06.getInstace();
System.out.println(s1);
System.out.println(s2);
<span class="token comment">//通过反射的方式调用私有构造器</span>
Class<span class="token generics function"><span class="token punctuation"><</span>SingletonDemo06<span class="token punctuation">></span></span> clz <span class="token operator">=</span> <span class="token punctuation">(</span>Class<span class="token generics function"><span class="token punctuation"><</span>SingletonDemo06<span class="token punctuation">></span></span><span class="token punctuation">)</span> SingletonDemo06<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">;</span>
Constructor<span class="token generics function"><span class="token punctuation"><</span>SingletonDemo06<span class="token punctuation">></span></span> cc <span class="token operator">=</span> clz<span class="token punctuation">.</span><span class="token function">getDeclaredConstructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
cc<span class="token punctuation">.</span><span class="token function">setAccessible</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
SingletonDemo06 s3 <span class="token operator">=</span> <span class="token punctuation">(</span>SingletonDemo06<span class="token punctuation">)</span>cc<span class="token punctuation">.</span><span class="token function">newInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
SingletonDemo06 s4 <span class="token operator">=</span> <span class="token punctuation">(</span>SingletonDemo06<span class="token punctuation">)</span>cc<span class="token punctuation">.</span><span class="token function">newInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>s3<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//Singleton.SingletonDemo06@2ff4acd0</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>s4<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//Singleton.SingletonDemo06@54bedef2</span>
}
很显然反射后的对象跟单例的hashcode不一样
解决反射的方式
在私有构造器加一层判断
public class SingletonDemo06 /*implements Serializable*/{
<span class="token keyword">private</span> <span class="token keyword">static</span> SingletonDemo06 instace<span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token function">SingletonDemo06</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//需要私有化构造器</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>null <span class="token operator">!=</span> instace<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
<span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">RuntimeException</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//防止反射下创建新的对象</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">//方法需要同步,调用效率低</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">synchronized</span> SingletonDemo06 <span class="token function">getInstace</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>null <span class="token operator">==</span> instace<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
instace <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SingletonDemo06</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> instace<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
反序列化Demo
public static void main(String[] args) throws Exception, SecurityException {
SingletonDemo06 s1 = SingletonDemo06.getInstace();
SingletonDemo06 s2 = SingletonDemo06.getInstace();
System.out.println(s1);//Singleton.SingletonDemo06@279f2327
System.out.println(s2);//Singleton.SingletonDemo06@279f2327
<span class="token comment">//通过反射的方式调用私有构造器</span>
// Class<SingletonDemo06> clz = (Class<SingletonDemo06>) SingletonDemo06.class;
// Constructor<SingletonDemo06> cc = clz.getDeclaredConstructor();
// cc.setAccessible(true);
// SingletonDemo06 s3 = (SingletonDemo06)cc.newInstance();
// SingletonDemo06 s4 = (SingletonDemo06)cc.newInstance();
// System.out.println(s3);//Singleton.SingletonDemo06@2ff4acd0
// System.out.println(s4);//Singleton.SingletonDemo06@54bedef2
<span class="token comment">//通过反序列化的方式构造多个对象</span>
FileOutputStream fos <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">FileOutputStream</span><span class="token punctuation">(</span><span class="token string">"d:/a.txt"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
ObjectOutputStream oos <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ObjectOutputStream</span><span class="token punctuation">(</span>fos<span class="token punctuation">)</span><span class="token punctuation">;</span>
oos<span class="token punctuation">.</span><span class="token function">writeObject</span><span class="token punctuation">(</span>s1<span class="token punctuation">)</span><span class="token punctuation">;</span>
oos<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
fos<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
ObjectInputStream ois <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ObjectInputStream</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">FileInputStream</span><span class="token punctuation">(</span><span class="token string">"d:/a.txt"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
SingletonDemo06 s3 <span class="token operator">=</span> <span class="token punctuation">(</span>SingletonDemo06<span class="token punctuation">)</span> ois<span class="token punctuation">.</span><span class="token function">readObject</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>s3<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//Singleton.SingletonDemo06@26a1ab54</span>
<span class="token punctuation">}</span>
解决方法readResolve()直接返回指定的单例对象
public class SingletonDemo06 implements Serializable{
<span class="token keyword">private</span> <span class="token keyword">static</span> SingletonDemo06 instace<span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token function">SingletonDemo06</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//需要私有化构造器</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>null <span class="token operator">!=</span> instace<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
<span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">RuntimeException</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//防止反射下创建新的对象</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">//方法需要同步,调用效率低</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">synchronized</span> SingletonDemo06 <span class="token function">getInstace</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>null <span class="token operator">==</span> instace<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
instace <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SingletonDemo06</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> instace<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//反序列化时,如果定义了readResolve()则直接返回此方法指定的对象。而不需要单独再创建新对象!</span>
<span class="token keyword">private</span> Object <span class="token function">readResolve</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">throws</span> Exception<span class="token punctuation">{</span>
<span class="token keyword">return</span> instace<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
总结:
单例模式的优点:
1、单例模式只产生一个实例,减少了性能的开销
2、当一个对象需要很多资源的时候,例如读取配置、产生依赖等,可以直接在启动时产生单例,让他永久驻留内存
3、单例可以让全局使用,达到优化资源共享
五种单例模式的实现方式比较:
- 饿汉式:线程安全,调用效率高。 但是,不能延时加载
- 懒汉式:线程安全,调用效率不高。 但是,可以延时加载
- 双重检测锁式:由于JVM底层内部模型原因,偶尔会出问题。不建议使用
- 静态内部类式:线程安全,调用效率高。 但是,可以延时加载
- 枚举单例:线程安全,调用效率高,不能延时加载
单例模式的应用:
1、Windows的Task Manager(任务管理器)、回收站就是很典型的单例模式
2、 应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作 ,否则内容不好追加。
3、spring容器的管理
工厂模式
主要是为了实现创建者和调用者的分离。通过工厂的方法代替new实例化对象,将实现类、创建对象统一管理和控制,达到调用者与实现者的解耦合。
简单工厂模式
一个抽象的接口,多个抽象接口的实现类,一个工厂类。弊端:一般是静态方法,对新增加的类必须修改代码。
public intereface Car{
void run();
}
public class Audi implements Car {
@Override
public void run() {
System.out.println("奥迪生产");
}
}
public class byd implements Car{
@Override
public void run() {
System.out.println("比亚迪生产");
}
}
//工厂类
public class CarFactory {
<span class="token keyword">public</span> <span class="token keyword">static</span> Car <span class="token function">createCar</span><span class="token punctuation">(</span>String type<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token string">"奥迪"</span><span class="token punctuation">.</span><span class="token function">equals</span><span class="token punctuation">(</span>type<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Audi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token string">"比亚迪"</span><span class="token punctuation">.</span><span class="token function">equals</span><span class="token punctuation">(</span>type<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">byd</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">else</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> null<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
}
public static void main(String[] args) {
//没有工厂创建类
Car cc1 = new Audi();
Car cc2 = new byd();
cc1.run();
cc2.run();
//工厂下创建类
Car c1 = CarFactory.createCar(“奥迪”);
Car c2 = CarFactory.createCar(“比亚迪”);
c1.run();
c2.run();
}
工厂方法模式
四个角色:抽象工厂模式、具体工厂模式、抽象产品、具体产品。实现抽象工厂的子类实现实例化,工厂方法弥补了简单工厂模式的缺点,区别在于:多了接口的工厂类。弊端:工厂方法模式的工厂类随着产品类个数增加而增加,从而增加了结构的复杂程度。
Demo
接口
public interface Car {
void run();
}
public interface CarFactory {
Car createCar();
}
实体类
public class Audi implements Car {
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"奥迪00000"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
public class AudiFactory implements CarFactory {
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> Car <span class="token function">createCar</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Audi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
public class byd implements Car {
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"比亚迪byd"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
public class BydFactory implements CarFactory {
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> Car <span class="token function">createCar</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Byd</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
public class Benz implements Car {
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"奔驰B!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
public class BenzFactory implements CarFactory {
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> Car <span class="token function">createCar</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Benz</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
但是工厂模式并没有简单工厂模式用的多。
抽象工厂模式
抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种、业务 分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。区别在于:工厂模式只生产单一的产品,抽象工厂模式中的工厂生产多个产品
Demo
public interface CarFactory {
Engine createEngine();
Seat createSeat();
Tyre createTyre();
}
public interface Tyre {
void revolve();
}
public interface Seat {
void massage();
}
class LuxurySeat implements Seat {
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">massage</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"全自动!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
class LowSeat implements Seat {
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">massage</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"手动!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
class LuxuryTyre implements Tyre {
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">revolve</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"米其林轮胎!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
class LowTyre implements Tyre {
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">revolve</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"普通轮胎!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
工厂实例
public class LowCarFactory implements CarFactory {
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> Seat <span class="token function">createSeat</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">LowSeat</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> Tyre <span class="token function">createTyre</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">LowTyre</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
public class LuxuryCarFactory implements CarFactory {
@Override
public Seat createSeat() {
return new LuxurySeat();
}
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> Tyre <span class="token function">createTyre</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">LuxuryTyre</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
总结:
1、 简单工厂模式:用的比较多,但在程序中并不是最好的
2、工厂方法模式 :不修改已有类的前提下,通过增加新的工厂类实现扩展。
3、抽象工厂模式 :可以对产品族扩展,但是不好增加产品
构建者模式
场景:如何构建一台手机?
因为会存在生产组件还有装配两个步骤才能生产出一台手机。
构建者模式就是适用于对象构建复杂的情况。通过构建和装配的解耦合。就可以有不同的装配,做出不同的对象。相同的装配也可能因为装配顺序导致对象不同。属于业务与算法的解耦。例StringBuilder的实现。
原型模式
类似于克隆,以一个对象为原型,复制出一个新的队象,并且具备原型的特点。直接克隆效率高。
实现:
1、Cloneable和clone方法
克隆存在的问题就是浅拷贝跟深拷贝。有学过指针的朋友就比较熟悉了。
浅拷贝问题:浅拷贝会导致两个对象都用同一块内存空间,导致数据公用
解决方法:深克隆,让已实现Clonable接口的类中的属性也实现Clonable接口
深克隆:让已实现Clonable接口的类中的属性也实现Clonable接口
Demo
浅拷贝
public class Sheep implements Cloneable,Serializable { //1997,英国的克隆羊,多利!
private String sname;
private Date birthday;
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">protected</span> Object <span class="token function">clone</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">throws</span> CloneNotSupportedException <span class="token punctuation">{</span>
Object obj <span class="token operator">=</span> <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">clone</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//直接调用object对象的clone()方法!</span>
<span class="token keyword">return</span> obj<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> String <span class="token function">getSname</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> sname<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setSname</span><span class="token punctuation">(</span>String sname<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>sname <span class="token operator">=</span> sname<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> Date <span class="token function">getBirthday</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> birthday<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setBirthday</span><span class="token punctuation">(</span>Date birthday<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>birthday <span class="token operator">=</span> birthday<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token function">Sheep</span><span class="token punctuation">(</span>String sname<span class="token punctuation">,</span> Date birthday<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">super</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>sname <span class="token operator">=</span> sname<span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>birthday <span class="token operator">=</span> birthday<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token function">Sheep</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token punctuation">}</span>
}
深拷贝
public class Sheep2 implements Cloneable { //1997,英国的克隆羊,多利!
private String sname;
private Date birthday;
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">protected</span> Object <span class="token function">clone</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">throws</span> CloneNotSupportedException <span class="token punctuation">{</span>
Object obj <span class="token operator">=</span> <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">clone</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//直接调用object对象的clone()方法!</span>
<span class="token comment">//添加如下代码实现深复制(deep Clone)</span>
Sheep2 s <span class="token operator">=</span> <span class="token punctuation">(</span>Sheep2<span class="token punctuation">)</span> obj<span class="token punctuation">;</span>
s<span class="token punctuation">.</span>birthday <span class="token operator">=</span> <span class="token punctuation">(</span>Date<span class="token punctuation">)</span> <span class="token keyword">this</span><span class="token punctuation">.</span>birthday<span class="token punctuation">.</span><span class="token function">clone</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//把属性也进行克隆!</span>
<span class="token keyword">return</span> obj<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> String <span class="token function">getSname</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> sname<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setSname</span><span class="token punctuation">(</span>String sname<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>sname <span class="token operator">=</span> sname<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> Date <span class="token function">getBirthday</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> birthday<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setBirthday</span><span class="token punctuation">(</span>Date birthday<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>birthday <span class="token operator">=</span> birthday<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token function">Sheep2</span><span class="token punctuation">(</span>String sname<span class="token punctuation">,</span> Date birthday<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">super</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>sname <span class="token operator">=</span> sname<span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>birthday <span class="token operator">=</span> birthday<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token function">Sheep2</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token punctuation">}</span>
}
总结:
1、如果需要创建大量对象,new会比原型模式低效
2、单例和原型是相反的,spring中创建bean就是这两种方式
结构型模式
适配器模式
适配器模式:是为了让原本由于接口不兼容而不能一起工作的那些类可以在一起工作。
目标接口(target):使用者用到的接口。可以是具体类/抽象类/接口 。
被适配的类(Adaaptee):需要适配的类
适配器(Adapter):将被适配的类包装成目标接口
Demo
//需要被适配的类
public class Adaptee {
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"客户请求"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
//通过继承方式的适配器
public class Adapter extends Adaptee implements Target {
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">handleReq</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// TODO 自动生成的方法存根</span>
<span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
//内部产生被适配对象
public class Adapter2 implements Target{
private Adaptee adaptee;
<span class="token keyword">public</span> <span class="token function">Adapter2</span><span class="token punctuation">(</span>Adaptee adaptee<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">super</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>adaptee <span class="token operator">=</span> adaptee<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">handleReq</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
adaptee<span class="token punctuation">.</span><span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
//目标接口
public interface Target {
<span class="token keyword">void</span> <span class="token function">handleReq</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
}
装饰者模式
动态地给一个对象增加新的功能。装饰模式是一种用于代替继承的方式,不需要再通过继承就能扩展对象的新功能。
举个例子:我想要一台智能、既上天又可以下水还能陆地跑的车。但是我现在只有一台普通的车,我就要给不同的厂家改装这台车,有智能公司、飞机公司等等。最后得到我想要的车
Component抽象:实现客户端跟实例对象的交互,如 io流中的InputStream、OutputStream接口
ConcreteComponent:真实对象,如 io流中的FileInputStream、FileOutputStream,例子中手上的普通车
Decorator装饰角色:抽象装饰接口,方便对真实对象添加功能
ConcreteDecorator具体装饰角色: 真正的装饰,给真正对象包装一层外衣。如Io流中的BufferedOutputStream、BufferedInputStream
Demo
public interface Icar {
<span class="token keyword">void</span> <span class="token function">move</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
}
//ConcreteComponent 具体构件角色(真实对象)
class car implements Icar{
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">move</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"地上跑"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
//Decorator 装饰
class SuperCar implements Icar{
protected Icar car;
<span class="token keyword">public</span> <span class="token function">SuperCar</span><span class="token punctuation">(</span>Icar car<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">super</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>car <span class="token operator">=</span> car<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">move</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
car<span class="token punctuation">.</span><span class="token function">move</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
//具体的装饰角色
class Flycar extends SuperCar{
public Flycar(Icar car) {
super(car);
}
public void fly() {
System.out.println(“天上飞”);
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">move</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">move</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">fly</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
//具体的装饰角色
class Swimcar extends SuperCar{
public Swimcar(Icar car) {
super(car);
}
public void swim() {
System.out.println(“水下游”);
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">move</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">move</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">swim</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
//具体的装饰角色
class AIcar extends SuperCar{
public AIcar(Icar car) {
super(car);
}
public void autoMove() {
System.out.println(“自动”);
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">move</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">move</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">autoMove</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
public static void main(String[] args) {
car car = new car();
car.move();
System.out.println("增加新的功能,飞行----------");
//手动地给car添加功能
Flycar flycar = new Flycar(car);
flycar.move();
System.out.println("既可以飞 又可以水下游");
SuperCar car2 = new Flycar(car);
Swimcar swimcar = new Swimcar(car2);
swimcar.move();
SuperCar car3 = new Flycar(new Swimcar(new AIcar(new SuperCar(new car()))));
car3.move();//自动、水下游、天上飞
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
总结:
1、装饰模式(Decorator)也叫包装器模式
2、装饰模式降低系统的耦合度,可以动态的增加或删除对象的职责,并使得需要装饰的具体构建类和具体装饰类可以独立变化,以便增加新的具体构建类和具体装饰类
3、 扩展对象功能,比继承灵活,不会导致类个数急剧增加
4、能够多次装饰,对不同的业务可以有多种组合
5、可以根据需要扩展装饰
弊端:
1、装饰者模式易出错,不容易调试错误
2、产生小的对象可能会影响性能
代理模式
将流程代码放到代理类中处理,通过代理控制对对象的访问。也是AOP(面向切面变成)的核心机制
举个例子:结婚可以选择专业的婚庆公司安排流程,原本没有婚庆公司新郎新娘就需要:准备工作->约酒店->节目安排->人员分工->结婚->其他事情。找了婚庆公司,婚庆公司就能完成准备工作->约酒店->节目安排->人员分工->其他事情。新郎新娘就只要完成结婚就行了。明星与经纪人也是,明星只要负责演出就行了,其余的琐事都是经纪人去完成
静态代理模式
Demo
public interface Star {
void sing();
}
public class RealStar implements Star {
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">sing</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"RealStar(明星本人).sing()"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
public class ProxyStar implements Star {
<span class="token keyword">private</span> Star star<span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token function">ProxyStar</span><span class="token punctuation">(</span>Star star<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">super</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>star <span class="token operator">=</span> star<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">sing</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"ProxyStar.bookTicket()"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"ProxyStar.collectMoney()"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"ProxyStar.confer()"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
star<span class="token punctuation">.</span><span class="token function">sing</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
动态代理
通过一个处理器接口反射,动态代理生成类和对象
java.lang.reflect.InvocationHandler(处理器接口)
1、可以通过invoke方法实现对真实角色的代理访问。
2、每次通过Proxy生成代理类对象对象时都要指定对应的处理器对象
public class StarHandler implements InvocationHandler{
<span class="token keyword">private</span> Star realstar<span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token function">StarHandler</span><span class="token punctuation">(</span>Star realstar<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">super</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>realstar <span class="token operator">=</span> realstar<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> Object <span class="token function">invoke</span><span class="token punctuation">(</span>Object proxy<span class="token punctuation">,</span> Method method<span class="token punctuation">,</span> Object<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token keyword">throws</span> Throwable <span class="token punctuation">{</span>
Object object <span class="token operator">=</span> null<span class="token punctuation">;</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>method<span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">equals</span><span class="token punctuation">(</span><span class="token string">"sing"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
object <span class="token operator">=</span> method<span class="token punctuation">.</span><span class="token function">invoke</span><span class="token punctuation">(</span>realstar<span class="token punctuation">,</span> null<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> object<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
生成代理对象方式
StarHandler handler = new StarHandler(realStar);
Star proxy = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
new Class[] {Star.class}, handler);
- 1
- 2
- 3
桥接模式
用于处理多层继承结构,处理多维度变化的场景,将各个维度设计成独立 的继承结构,使各个维度可以独立的扩展在抽象层建立关联。
桥接模式:其实就是通过桥把两个变化维度连在一起,让每个维度可以随意变化
组合模式
将整个关系变成树形结构。
抽象构件(Component)角色: 定义了叶子和容器构件的共同点
叶子(Leaf)构件角色:无子节点
容器(Composite)构件角色: 有容器特征,可以包含子节点,其中某个子类可以对Composite下所有子类操作
外观模式
调用者减少跟每一个实体的使用
例如要注册某个公司,正常流程是:总经理去找工商局审核、去税务局登记、去银行开户等等
外观模式是实现了给总经理安排一个下手,下手去干这些事情,总经理只要一声令下
享元模式
享元模式是为了节省内存,将相同或相似的对象共享重用。
内部状态:可以共享,不会随环境变化而改变
外部状态:不可以共享,会随环境变化而改变
举个例子:
生产一种面包,它的大小颜色口味都是一样的,唯独最后打上的生产日期不一样。所以面包类应该有大小颜色口味等属性,唯独要专门弄一个生产日期的类给面包设定不一样的生产日期
总结:
1、极大减少内存中对象的数量,因为不同批次的面包会有很多个面包类,但是用addDate类就只要控制addDate类
2、 相同或相似对象内存中只存一份,极大的节约资源,提高系统性能
3、外部状态相对独立,不影响内部状态
结构型模式总结
行为型模式
观察者模式
观察者模式就像一个广播,通常是1:N的方式。当一个目标对象(Subject)发生改变时,需要告知一系列观察者对象。举个例子:一个电台主播临时决定今晚不开播,就需要告诉那些关注他的人今天有事没有开播。这种情况下目标对象就是这个主播,观察者就是这些观众。
主要实现方式就是把观察者放入容器中,保持观察者跟目标对象的一致性
//目标对象基本方法
public class Subject {
<span class="token keyword">protected</span> List<span class="token generics function"><span class="token punctuation"><</span>Observer<span class="token punctuation">></span></span> list <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayList</span><span class="token generics function"><span class="token punctuation"><</span>Observer<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">registerObserver</span><span class="token punctuation">(</span>Observer obs<span class="token punctuation">)</span><span class="token punctuation">{</span>
list<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>obs<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">removeObserver</span><span class="token punctuation">(</span>Observer obs<span class="token punctuation">)</span><span class="token punctuation">{</span>
list<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>obs<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//通知所有的观察者更新状态</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">notifyAllObservers</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span>Observer obs <span class="token operator">:</span> list<span class="token punctuation">)</span> <span class="token punctuation">{</span>
obs<span class="token punctuation">.</span><span class="token function">update</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
}
public class ConcreteSubject extends Subject {
<span class="token keyword">private</span> <span class="token keyword">int</span> state<span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">getState</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> state<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setState</span><span class="token punctuation">(</span><span class="token keyword">int</span> state<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>state <span class="token operator">=</span> state<span class="token punctuation">;</span>
<span class="token comment">//主题对象(目标对象)值发生了变化,请通知所有的观察者</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">notifyAllObservers</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
public interface Observer {
void update(Subject subject);
}
public class ObserverA implements Observer {
<span class="token keyword">private</span> <span class="token keyword">int</span> myState<span class="token punctuation">;</span> <span class="token comment">//myState需要跟目标对象的state值保持一致!</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">update</span><span class="token punctuation">(</span>Subject subject<span class="token punctuation">)</span> <span class="token punctuation">{</span>
myState <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>ConcreteSubject<span class="token punctuation">)</span>subject<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getState</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">getMyState</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> myState<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setMyState</span><span class="token punctuation">(</span><span class="token keyword">int</span> myState<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>myState <span class="token operator">=</span> myState<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
public static void main(String[] args) {
//目标对象
ConcreteSubject subject = new ConcreteSubject();
<span class="token comment">//创建多个观察者</span>
ObserverA obs1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ObserverA</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
ObserverA obs2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ObserverA</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
ObserverA obs3 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ObserverA</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//将这三个观察者添加到subject对象的观察者队伍中</span>
subject<span class="token punctuation">.</span><span class="token function">registerObserver</span><span class="token punctuation">(</span>obs1<span class="token punctuation">)</span><span class="token punctuation">;</span>
subject<span class="token punctuation">.</span><span class="token function">registerObserver</span><span class="token punctuation">(</span>obs2<span class="token punctuation">)</span><span class="token punctuation">;</span>
subject<span class="token punctuation">.</span><span class="token function">registerObserver</span><span class="token punctuation">(</span>obs3<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//改变subject的状态</span>
subject<span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token number">3000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//我们看看,观察者的状态是不是也发生了变化</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>obs1<span class="token punctuation">.</span><span class="token function">getMyState</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>obs2<span class="token punctuation">.</span><span class="token function">getMyState</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>obs3<span class="token punctuation">.</span><span class="token function">getMyState</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
应用:
Servlet中,监听器的实现
服务器对客户端的推送
责任链模式
将能够处理同一类请求的对象连成一条链,请求沿链传递,链上的对象能处理该请求就处理,不能就给下一个。举个例子:大学生请假,请假少于3天,辅导员就有权利批,大于3天小于7天,就得给院主任批,大于7天小于30天,就得给院长批,大于30天就让校长把你休学。
核心也是基于if else实现,不过不是if else 的嵌套,通过链表把这些负责人连接在一起。
Demo
请假信息封装
public class LeaveRequest {
private String empName;
private int leaveDays;
private String reason;
<span class="token keyword">public</span> <span class="token function">LeaveRequest</span><span class="token punctuation">(</span>String empName<span class="token punctuation">,</span> <span class="token keyword">int</span> leaveDays<span class="token punctuation">,</span> String reason<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">super</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>empName <span class="token operator">=</span> empName<span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>leaveDays <span class="token operator">=</span> leaveDays<span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>reason <span class="token operator">=</span> reason<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> String <span class="token function">getEmpName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> empName<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setEmpName</span><span class="token punctuation">(</span>String empName<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>empName <span class="token operator">=</span> empName<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">getLeaveDays</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> leaveDays<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setLeaveDays</span><span class="token punctuation">(</span><span class="token keyword">int</span> leaveDays<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>leaveDays <span class="token operator">=</span> leaveDays<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> String <span class="token function">getReason</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> reason<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setReason</span><span class="token punctuation">(</span>String reason<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>reason <span class="token operator">=</span> reason<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
领导的类
public abstract class Leader {
protected String name;
protected Leader nextLeader; //责任链上的后继对象
<span class="token keyword">public</span> <span class="token function">Leader</span><span class="token punctuation">(</span>String name<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">super</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//设定责任链上的后继对象</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setNextLeader</span><span class="token punctuation">(</span>Leader nextLeader<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>nextLeader <span class="token operator">=</span> nextLeader<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">/**
* 处理请求的核心的业务方法
* @param request
*/</span>
<span class="token keyword">public</span> <span class="token keyword">abstract</span> <span class="token keyword">void</span> <span class="token function">handleRequest</span><span class="token punctuation">(</span>LeaveRequest request<span class="token punctuation">)</span><span class="token punctuation">;</span>
}
public class Director extends Leader {
<span class="token keyword">public</span> <span class="token function">Director</span><span class="token punctuation">(</span>String name<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">super</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">handleRequest</span><span class="token punctuation">(</span>LeaveRequest request<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span><span class="token function">getLeaveDays</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator"><</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"学生:"</span><span class="token operator">+</span>request<span class="token punctuation">.</span><span class="token function">getEmpName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">"请假,天数:"</span><span class="token operator">+</span>request<span class="token punctuation">.</span><span class="token function">getLeaveDays</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">",理由:"</span><span class="token operator">+</span>request<span class="token punctuation">.</span><span class="token function">getReason</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"主任:"</span><span class="token operator">+</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token operator">+</span><span class="token string">",审批通过!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token keyword">else</span><span class="token punctuation">{</span>
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>nextLeader<span class="token operator">!=</span>null<span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>nextLeader<span class="token punctuation">.</span><span class="token function">handleRequest</span><span class="token punctuation">(</span>request<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
}
public class Manager extends Leader {
<span class="token keyword">public</span> <span class="token function">Manager</span><span class="token punctuation">(</span>String name<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">super</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">handleRequest</span><span class="token punctuation">(</span>LeaveRequest request<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span><span class="token function">getLeaveDays</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator"><</span><span class="token number">7</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"学生:"</span><span class="token operator">+</span>request<span class="token punctuation">.</span><span class="token function">getEmpName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">"请假,天数:"</span><span class="token operator">+</span>request<span class="token punctuation">.</span><span class="token function">getLeaveDays</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">",理由:"</span><span class="token operator">+</span>request<span class="token punctuation">.</span><span class="token function">getReason</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"院长:"</span><span class="token operator">+</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token operator">+</span><span class="token string">",审批通过!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token keyword">else</span><span class="token punctuation">{</span>
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>nextLeader<span class="token operator">!=</span>null<span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>nextLeader<span class="token punctuation">.</span><span class="token function">handleRequest</span><span class="token punctuation">(</span>request<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
}
public class GeneralManager extends Leader {
<span class="token keyword">public</span> <span class="token function">GeneralManager</span><span class="token punctuation">(</span>String name<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">super</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">handleRequest</span><span class="token punctuation">(</span>LeaveRequest request<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span><span class="token function">getLeaveDays</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator"><</span><span class="token number">30</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"学生:"</span><span class="token operator">+</span>request<span class="token punctuation">.</span><span class="token function">getEmpName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">"请假,天数:"</span><span class="token operator">+</span>request<span class="token punctuation">.</span><span class="token function">getLeaveDays</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">",理由:"</span><span class="token operator">+</span>request<span class="token punctuation">.</span><span class="token function">getReason</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"校长:"</span><span class="token operator">+</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token operator">+</span><span class="token string">",审批通过!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token keyword">else</span><span class="token punctuation">{</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span><span class="token function">getEmpName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">"回家休学,居然请假"</span><span class="token operator">+</span>request<span class="token punctuation">.</span><span class="token function">getLeaveDays</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">"天!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
}
总结:
1、可以随时增加新的管理层
2、servlet过滤器的处理
迭代模式(iterator)
分为聚合对象(用于存储数据)和迭代器(用于遍历数据)。在set/map/list这些数据结构中都有应用
Demo-自定义迭代器
public interface MyIterator {
void first(); //将游标指向第一个元素
void next(); //将游标指向下一个元素
boolean hasNext();//判断是否存在下一个元素
<span class="token keyword">boolean</span> <span class="token function">isFirst</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">boolean</span> <span class="token function">isLast</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
Object <span class="token function">getCurrentObj</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//获取当前游标指向的对象</span>
}
public class ConcreteMyAggregate {
private List<Object> list = new ArrayList<Object>();
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">addObject</span><span class="token punctuation">(</span>Object obj<span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>list<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">removeObject</span><span class="token punctuation">(</span>Object obj<span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>list<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> List<span class="token generics function"><span class="token punctuation"><</span>Object<span class="token punctuation">></span></span> <span class="token function">getList</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> list<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setList</span><span class="token punctuation">(</span>List<span class="token generics function"><span class="token punctuation"><</span>Object<span class="token punctuation">></span></span> list<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>list <span class="token operator">=</span> list<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//获得迭代器</span>
<span class="token keyword">public</span> MyIterator <span class="token function">createIterator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">ConcreteIterator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//使用内部类定义迭代器,可以直接使用外部类的属性</span>
<span class="token keyword">private</span> <span class="token keyword">class</span> <span class="token class-name">ConcreteIterator</span> <span class="token keyword">implements</span> <span class="token class-name">MyIterator</span> <span class="token punctuation">{</span>
<span class="token keyword">private</span> <span class="token keyword">int</span> cursor<span class="token punctuation">;</span> <span class="token comment">//定义游标用于记录遍历时的位置,类似于c语言的指针</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">first</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
cursor <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> Object <span class="token function">getCurrentObj</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> list<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>cursor<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">hasNext</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>cursor<span class="token operator"><</span>list<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">isFirst</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> cursor<span class="token operator">==</span><span class="token number">0</span><span class="token operator">?</span><span class="token boolean">true</span><span class="token operator">:</span><span class="token boolean">false</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">isLast</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> cursor<span class="token operator">==</span><span class="token punctuation">(</span>list<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token operator">?</span><span class="token boolean">true</span><span class="token operator">:</span><span class="token boolean">false</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>cursor<span class="token operator"><</span>list<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
cursor<span class="token operator">++</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
}
中介者模式
一个项目不可能只是一个部门完成。需要多个部门完成,但是部门之间不应该乱七八糟地混为一滩,就需要一个中间者调动每个部门的事情。这个中间者就是中介者。这是结构就变成了这样
总结:
1、解耦同级对象之间的交互关系。每个对象都持有中介者对象的引 用,有什么事情只跟中介者对象打交道。我们通过中介者对象统一管理这些交互关系
2、MVC中controller就是中介者模式
命令模式
对这个有很多理论的解释,就不说理论了。举个例子:国家给地方政府下达命令,地方政府不需要知道时谁下达的命令,国家也不需要知道是谁去执行命令,双方只要通过命令达成协议就行了。
写个Demo,就懂了
//调用者/发起者
public class Invoke {
<span class="token keyword">private</span> Command command<span class="token punctuation">;</span> <span class="token comment">//也可以通过容器List<Command>容纳很多命令对象,进行批处理。数据库底层的事务管理就是类似的结构!</span>
<span class="token keyword">public</span> <span class="token function">Invoke</span><span class="token punctuation">(</span>Command command<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">super</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>command <span class="token operator">=</span> command<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//业务方法 ,用于调用命令类的方法</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">call</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
command<span class="token punctuation">.</span><span class="token function">execute</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
public interface Command {
/**
* 这个方法是一个返回结果为空的方法。
* 实际项目中,可以根据需求设计多个不同的方法
*/
void execute();
}
class ConcreteCommand implements Command {
<span class="token keyword">private</span> Receiver receiver<span class="token punctuation">;</span> <span class="token comment">//命令的真正的执行者</span>
<span class="token keyword">public</span> <span class="token function">ConcreteCommand</span><span class="token punctuation">(</span>Receiver receiver<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">super</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>receiver <span class="token operator">=</span> receiver<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">execute</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">//命令真正执行前或后,执行相关的处理!</span>
receiver<span class="token punctuation">.</span><span class="token function">action</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
//真正执行的人,是不需要跟invoker有联系的
public class Receiver {
public void action(){
System.out.println(“Receiver.action()”);
}
}
策略模式
策略模式对应于解决某一个问题的一个算法族,允许用户从该算法族中任选一个算法解决某一问题,同时可以方便的更换算法或者增加新的算法。并且由客户端决定调用哪个算法。 举个例子:在售货过程中,对新客户可能会给原价,对小批量的用户会打9折,对老客户会打8.5折,对老客户大批量打8折。用大量的if-else确实可以实现策略模式,但是代码可读性不强。策略模式就是专门用于实现算法分离。由client去选择策略。
状态模式
解决系统中复杂对象的状态转换以及不同状态下行为的封装问题
Context:维护一个State对象,让该对象的状态随时改变
ConcreteState具体状态类:每一个类又是一个状态
备忘录模式
Ctrl+Z相信大家都使用过,怎么把刚刚修改的东西恢复成原状,这就是备忘录模式。实现原理:保存某个对象内部状态的拷贝,这样以后就可以将该对象恢复到原先的状态。
Emp:为当前使用的对象
EmpMements是备忘对象,与emp属性保持一致
CareTaker:负责管理备忘的对象
Demo
//当前对象
public class Emp {
private String ename;
private int age;
private double salary;
<span class="token comment">//进行备忘操作,并返回备忘录对象</span>
<span class="token keyword">public</span> EmpMemento <span class="token function">memento</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">EmpMemento</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//进行数据恢复,恢复成制定备忘录对象的值</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">recovery</span><span class="token punctuation">(</span>EmpMemento mmt<span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>ename <span class="token operator">=</span> mmt<span class="token punctuation">.</span><span class="token function">getEname</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> mmt<span class="token punctuation">.</span><span class="token function">getAge</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>salary <span class="token operator">=</span> mmt<span class="token punctuation">.</span><span class="token function">getSalary</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token function">Emp</span><span class="token punctuation">(</span>String ename<span class="token punctuation">,</span> <span class="token keyword">int</span> age<span class="token punctuation">,</span> <span class="token keyword">double</span> salary<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">super</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>ename <span class="token operator">=</span> ename<span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>salary <span class="token operator">=</span> salary<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> String <span class="token function">getEname</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> ename<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setEname</span><span class="token punctuation">(</span>String ename<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>ename <span class="token operator">=</span> ename<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">getAge</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> age<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setAge</span><span class="token punctuation">(</span><span class="token keyword">int</span> age<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">double</span> <span class="token function">getSalary</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> salary<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setSalary</span><span class="token punctuation">(</span><span class="token keyword">double</span> salary<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>salary <span class="token operator">=</span> salary<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
//管理备忘录
public class CareTaker {
<span class="token keyword">private</span> EmpMemento memento<span class="token punctuation">;</span>
// private List<EmpMemento> list = new ArrayList<EmpMemento>();
<span class="token keyword">public</span> EmpMemento <span class="token function">getMemento</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> memento<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setMemento</span><span class="token punctuation">(</span>EmpMemento memento<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>memento <span class="token operator">=</span> memento<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
//备忘录类
public class EmpMemento {
private String ename;
private int age;
private double salary;
<span class="token keyword">public</span> <span class="token function">EmpMemento</span><span class="token punctuation">(</span>Emp e<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>ename <span class="token operator">=</span> e<span class="token punctuation">.</span><span class="token function">getEname</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> e<span class="token punctuation">.</span><span class="token function">getAge</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>salary <span class="token operator">=</span> e<span class="token punctuation">.</span><span class="token function">getSalary</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> String <span class="token function">getEname</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> ename<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setEname</span><span class="token punctuation">(</span>String ename<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>ename <span class="token operator">=</span> ename<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">getAge</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> age<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setAge</span><span class="token punctuation">(</span><span class="token keyword">int</span> age<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">double</span> <span class="token function">getSalary</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> salary<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setSalary</span><span class="token punctuation">(</span><span class="token keyword">double</span> salary<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>salary <span class="token operator">=</span> salary<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
public static void main(String[] args) {
CareTaker taker = new CareTaker();
Emp emp <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Emp</span><span class="token punctuation">(</span><span class="token string">"atcain"</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"第一次打印对象:"</span><span class="token operator">+</span>emp<span class="token punctuation">.</span><span class="token function">getEname</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">"---"</span><span class="token operator">+</span>emp<span class="token punctuation">.</span><span class="token function">getAge</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">"---"</span><span class="token operator">+</span>emp<span class="token punctuation">.</span><span class="token function">getSalary</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//第一次打印对象:atcain---20---0</span>
taker<span class="token punctuation">.</span><span class="token function">setMemento</span><span class="token punctuation">(</span>emp<span class="token punctuation">.</span><span class="token function">memento</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//备忘一次</span>
emp<span class="token punctuation">.</span><span class="token function">setAge</span><span class="token punctuation">(</span><span class="token number">15</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
emp<span class="token punctuation">.</span><span class="token function">setEname</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
emp<span class="token punctuation">.</span><span class="token function">setSalary</span><span class="token punctuation">(</span><span class="token number">9000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"第二次打印对象:"</span><span class="token operator">+</span>emp<span class="token punctuation">.</span><span class="token function">getEname</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">"---"</span><span class="token operator">+</span>emp<span class="token punctuation">.</span><span class="token function">getAge</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">"---"</span><span class="token operator">+</span>emp<span class="token punctuation">.</span><span class="token function">getSalary</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//第二次打印对象:hello---15---9000</span>
emp<span class="token punctuation">.</span><span class="token function">recovery</span><span class="token punctuation">(</span>taker<span class="token punctuation">.</span><span class="token function">getMemento</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//恢复到备忘录对象保存的状态</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"第三次打印对象:"</span><span class="token operator">+</span>emp<span class="token punctuation">.</span><span class="token function">getEname</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">"---"</span><span class="token operator">+</span>emp<span class="token punctuation">.</span><span class="token function">getAge</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">"---"</span><span class="token operator">+</span>emp<span class="token punctuation">.</span><span class="token function">getSalary</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//第三次打印对象:atcain---20---0</span>
<span class="token punctuation">}</span>
剩下解释器模式、访问者模式、模板方法模式很少见到过,如果以后学习的过程中遇到了,再加进来
行为型模式总结
图源于百度,侵权删
</div><div><div></div></div>
<link href="https://csdnimg/release/phoenix/mdeditor/markdown_views-60ecaf1f42.css" rel="stylesheet">
</div>
更多推荐
23种设计模式学习
发布评论