[java笔记]常用的设计模式
1.单例设计模式
单例设计模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
1)构造方法私有化
2)声明一个本类对象
3)给外部提供一个静态方法获取对象实例
例如:
class Singleton{
private static Singletho1 s = new Singletho1();
private Singletho1(){}
public static Singletho1 getInstance(){
return s;
}
}
2.模板方法模式(Templete Method)
模板方法模式:定义一个操作中的算法的骨架,而将一些可变部分的实现延迟到子类中。模板方法模式使得子类可以不改变
一个算法的结构即可重新定义该算法的某些特定的步骤。
3.策略模式(Strategy Pattern)
策略模式:定义了一系列的算法,将每一种算法封装起来并可以互相替换使用,策略模式让算法独立于使用它的客户应用而独立变化
OO设计原则:
1)面向接口编程(面向抽象编程)
2)封装变化(把可变化的东西抽象出来,单独封装起来)
3)多用组合,少用继承
4)对修改关闭,对扩展开放
4.简单工厂模式
简单工厂模式:由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单使用的模式。
例如:
1 public class FactoryDemo { 2 3 public static void main(String[] args) { 4 5 Doll clothDoll = DollFactory.getInstance("cloth"); 6 if(clothDoll != null){ 7 System.out.println(clothDoll.getInfo()); 8 } 9 Doll barbieDoll = DollFactory.getInstance("barbie"); 10 if(barbieDoll != null){ 11 System.out.println(barbieDoll.getInfo()); 12 } 13 14 } 15 16 } 17 18 19 /** 20 * @ClassName: DollFactory 21 * @Description: 工厂类 22 * @date 2015年1月16日 上午11:03:18 23 */ 24 class DollFactory{ 25 //值负责产生对象 26 public static Doll getInstance (String name){ 27 //根据条件不同的对象 28 if("cloth".equals(name)){ 29 return new ClothDoll(); 30 }else if ("barbie".equals(name)){ 31 return new BarbieDoll(); 32 } 33 return null; 34 } 35 36 } 37 38 /** 39 * @ClassName: Doll 40 * @Description: 娃娃类 41 * @date 2015年1月16日 上午11:03:13 42 */ 43 interface Doll{ 44 45 public String getInfo(); 46 } 47 48 /** 49 * @ClassName: ClothDoll 50 * @Description: 布娃娃 51 * @date 2015年1月16日 上午11:03:09 52 */ 53 class ClothDoll implements Doll{ 54 55 public String getInfo(){ 56 return "我是布娃娃。"; 57 } 58 } 59 60 61 /** 62 * @ClassName: BarbieDoll 63 * @Description: 芭比娃娃 64 * @date 2015年1月16日 上午11:03:03 65 */ 66 class BarbieDoll implements Doll{ 67 68 public String getInfo(){ 69 return "我是芭比娃娃."; 70 } 71 }
5.代理设计模式
代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。代理模式说白了就是“真实对象”的代表,在
访问对象时引入一定程度的间接性,因为这种间接性可以附件多种用途。
静态代理:
1 /** 2 * @Title: ProxyDemo.java 3 * @Package proxydemo 4 * @Description: TODO 5 * @date 2015年1月16日 下午7:33:00 6 * @version V1.0 7 */ 8 package proxydemo; 9 10 /** 11 * @ClassName: ProxyDemo 12 * @Description: 代理模式:为其他对象提供一种代理以控制对这个对象的访问。 13 * @date 2015年1月16日 下午7:33:00 14 */ 15 public class ProxyDemo { 16 17 /** 18 * @Title: main 19 * @Description: TODO 20 * @param args 21 * @return void 22 */ 23 public static void main(String[] args) { 24 25 Person p = new Person("小白"); 26 //创建代理对象,并把代理对象传进来 27 Matchmaker m = new Matchmaker(p); 28 29 m.miai();//相亲 30 } 31 32 } 33 34 35 /** 36 * @ClassName: Subject 37 * @Description: 主题接口 38 * @date 2015年1月16日 下午7:37:46 39 */ 40 interface Subject{ 41 42 public void miai(); 43 44 } 45 46 47 /** 48 * @ClassName: Person 49 * @Description: 被代理类 50 * @date 2015年1月16日 下午7:37:25 51 */ 52 class Person implements Subject{ 53 54 private String name; 55 56 public Person(String name){ 57 this.name = name; 58 } 59 60 public void miai(){ 61 System.out.println(name+"正在相亲中。。。"); 62 } 63 64 } 65 66 67 /** 68 * @ClassName: Matchamker 69 * @Description: 代理类 70 * @date 2015年1月16日 下午7:36:58 71 */ 72 class Matchmaker implements Subject{ 73 74 private Subject target;//要代理的目标对象 75 76 public Matchmaker(Subject target){ 77 this.target = target; 78 } 79 80 //相亲之前要做的事情 81 private void before(){ 82 System.out.println("为代理人匹配如意郎君。"); 83 } 84 85 //相亲之后要做的事情 86 private void after(){ 87 System.out.println("本次相亲结束。"); 88 } 89 90 //相亲方法 91 public void miai(){ 92 before(); 93 //真正执行相亲方法 94 target.miai(); 95 after(); 96 } 97 }
动态代理:Proxy的代理,接口和实现类之间可以不直接发生联系,而可以再运行期(Runtime)实现动态关联。
1 /** 2 * @Title: Subject.java 3 * @Package dynaproxy 4 * @Description: TODO 5 * @date 2015年2月23日 下午8:37:49 6 * @version V1.0 7 */ 8 package dynaproxy; 9 10 /** 11 * @ClassName: Subject 12 * @Description: 要代理的主题接口 13 * @date 2015年2月23日 下午8:37:49 14 */ 15 public interface Subject { 16 17 /** 18 * @Title: miai 19 * @Description: 相亲 20 * @return void 21 */ 22 public void miai(); 23 24 } 25 26 27 /** 28 * @Title: Person.java 29 * @Package dynaproxy 30 * @Description: TODO 31 * @date 2015年2月23日 下午8:39:12 32 * @version V1.0 33 */ 34 package dynaproxy; 35 36 /** 37 * @ClassName: Person 38 * @Description: TODO 39 * @date 2015年2月23日 下午8:39:12 40 */ 41 public class Person implements Subject{ 42 43 private String name; 44 45 public Person(String name){ 46 this.name = name; 47 } 48 49 /* (non-Javadoc) 50 * <p>Title: miai</p> 51 * <p>Description: </p> 52 * @see dynaproxy.Subject#miai() 53 */ 54 @Override 55 public void miai() { 56 57 System.out.println(name+"正在相亲中。。"); 58 59 } 60 61 } 62 63 /** 64 * @Title: DynaProxy.java 65 * @Package dynaproxy 66 * @Description: TODO 67 * @date 2015年2月23日 下午8:40:47 68 * @version V1.0 69 */ 70 package dynaproxy; 71 72 import java.lang.reflect.InvocationHandler; 73 import java.lang.reflect.Method; 74 75 /** 76 * @ClassName: DynaProxy 77 * @Description: 动态代理类 78 * @date 2015年2月23日 下午8:40:47 79 */ 80 public class DynaProxy implements InvocationHandler{ 81 82 private Object target; 83 public DynaProxy(Object target){ 84 this.target = target; 85 } 86 87 88 /* (non-Javadoc) 89 * <p>Title: invoke</p> 90 * <p>Description: </p> 91 * @param proxy 92 * @param method 93 * @param args 94 * @return 95 * @throws Throwable 96 * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]) 97 */ 98 @Override 99 public Object invoke(Object proxy, Method method, Object[] args) 100 throws Throwable { 101 Object obj = null; 102 before(); 103 //正真调用业务方法 104 obj = method.invoke(target, args); 105 after(); 106 return obj; 107 } 108 109 110 /** 111 * @Title: after 112 * @Description: 相亲之后要做的事情 113 * @return void 114 */ 115 116 private void after() { 117 System.out.println("本次相亲结束。"); 118 } 119 120 /** 121 * @Title: before 122 * @Description: 相亲之前要做的事情 123 * @return void 124 */ 125 126 private void before() { 127 System.out.println("为代理人匹配如意郎君。"); 128 } 129 130 131 } 132 133 /** 134 * @Title: Test.java 135 * @Package dynaproxy 136 * @Description: TODO 137 * @date 2015年2月23日 下午8:49:10 138 * @version V1.0 139 */ 140 package dynaproxy; 141 142 import java.lang.reflect.Proxy; 143 144 /** 145 * @ClassName: Test 146 * @Description: TODO 147 * @date 2015年2月23日 下午8:49:10 148 */ 149 public class Test { 150 151 public static void main(String[] args) { 152 153 Person p = new Person("小白"); 154 DynaProxy dp = new DynaProxy(p); 155 156 /* 157 * Proxy提供用于创建动态代理类和实例的静态方法, 158 * 它还是这些方法创建的所有动态代理类的超类。 159 */ 160 //动态生成代理对象(类加载器,被代理接口,InvocationHandler) 161 Subject s = (Subject) Proxy.newProxyInstance(p.getClass() 162 .getClassLoader(), p.getClass().getInterfaces(), dp); 163 s.miai(); 164 } 165 166 }
6.适配器模式
适配器模式(Adapter):将一个类的接口装换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一
起工作的那些类可以一起工作。
例如:
1 /** 2 * @Title: AdapterDemo.java 3 * @Package adapterdemo 4 * @Description: TODO 5 * @date 2015年1月16日 下午8:03:11 6 * @version V1.0 7 */ 8 package adapterdemo; 9 10 /** 11 * @ClassName: AdapterDemo 12 * @Description: 适配器模式(Adapter):将一个类的接口装换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 13 * @date 2015年1月16日 下午8:03:11 14 */ 15 public class AdapterDemo { 16 17 /** 18 * @Title: main 19 * @Description: TODO 20 * @param args 21 * @return void 22 */ 23 public static void main(String[] args) { 24 25 PowerA powerA = new PowerAImpl(); 26 start(powerA); 27 28 PowerB powerB = new PowerBImpl(); 29 //把powerB封装进适配器 30 PowerAAdapter pa = new PowerAAdapter(powerB); 31 start(pa); 32 33 } 34 35 //开始工作 36 public static void start(PowerA powerA){ 37 powerA.insert(); 38 } 39 40 } 41 42 43 /** 44 * @ClassName: PowerAAdapter 45 * @Description: 适配器类 46 * @date 2015年1月16日 下午8:31:59 47 */ 48 class PowerAAdapter implements PowerA{ 49 50 private PowerB powerB;//要进行适配的接口 51 52 public PowerAAdapter(PowerB powerB){ 53 this.powerB = powerB; 54 } 55 56 public void insert(){ 57 powerB.connect(); 58 } 59 60 } 61 62 63 /** 64 * @ClassName: PowerA 65 * @Description: 电源A接口 66 * @date 2015年1月16日 下午8:05:11 67 */ 68 interface PowerA{ 69 70 public void insert(); 71 72 } 73 74 75 /** 76 * @ClassName: PowerAImpl 77 * @Description: TODO 78 * @date 2015年1月16日 下午8:07:33 79 */ 80 class PowerAImpl implements PowerA{ 81 82 public void insert(){ 83 System.out.println("电源A接口插入,开始工作。"); 84 } 85 86 } 87 88 89 /** 90 * @ClassName: PowerB 91 * @Description: 电源B接口 92 * @date 2015年1月16日 下午8:05:54 93 */ 94 interface PowerB{ 95 96 public void connect(); 97 98 } 99 100 /** 101 * @ClassName: PowerBImpl 102 * @Description: TODO 103 * @date 2015年1月16日 下午8:08:49 104 */ 105 class PowerBImpl implements PowerB{ 106 107 public void connect(){ 108 System.out.println("电源B接口以连接,开始工作。"); 109 } 110 111 }
7.享元设计模式
享元设计模式(Flyweight Pattern):它使用共享对象,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似对象;
它适合用于当大量对象只是重复因而导致无法令人接受的使用大量内存。通常对象中的部分状态是可以分享的。常见做法是把
他们放在外部数据结构,当需要使用时再将他们传递给享元。
运用共享技术有效的支持大量细粒度的对象。
例如:Integrate在一个字节内的对象。
8.装饰者设计模式
装饰着设计模式(Decorator):动态地给对象添加一些额外的职责。就添加功能来说,Decorator模式相比生成子类更为灵活。
改模式以对客户透明的方式扩展对象的功能。
涉及角色:
1)抽象构件角色:定义一个抽象接口,来规范准备附加功能的类。
2)具体构件角色:将要被附加功能的类,实现抽象构件角色接口。
3)抽象装饰者角色:将有对具体构件角色的引用并定义与抽象构件角色一致的接口。
4)具体装饰角色:实现抽象装饰者角色,负责为具体构件添加额外功能。
示例代码:
1 package decoratorDemo; 2 3 /** 4 * @ClassName: Drink 5 * @Description: 被装饰者对象接口 6 * @date 2015年2月5日 下午9:23:33 7 */ 8 public interface Drink { 9 10 //饮料的描述 11 public String description(); 12 13 //计算价格 14 public float cost(); 15 16 } 17 18 19 package decoratorDemo; 20 21 /** 22 * @ClassName: SoyaBeanMilk 23 * @Description: 具体的被装饰者对象: 豆浆 24 * @date 2015年2月5日 下午9:26:13 25 */ 26 public class SoyaBeanMilk implements Drink{ 27 28 /* (non-Javadoc) 29 * <p>Title: decription</p> 30 * <p>Description: </p> 31 * @return 32 * @see decoratorDemo.Drink#decription() 33 */ 34 @Override 35 public String description() { 36 return "纯豆浆"; 37 } 38 39 /* (non-Javadoc) 40 * <p>Title: cost</p> 41 * <p>Description: </p> 42 * @return 43 * @see decoratorDemo.Drink#cost() 44 */ 45 @Override 46 public float cost() { 47 return 5f; 48 } 49 50 } 51 52 53 package decoratorDemo; 54 55 /** 56 * @ClassName: Decorator 57 * @Description: 装饰者基类 58 * @date 2015年2月5日 下午9:29:37 59 */ 60 public abstract class Decorator implements Drink{ 61 62 private Drink drink;//要装饰的对象 63 64 public Decorator(Drink drink){ 65 this.drink = drink; 66 } 67 68 /* (non-Javadoc) 69 * <p>Title: decription</p> 70 * <p>Description: </p> 71 * @return 72 * @see decoratorDemo.Drink#decription() 73 */ 74 @Override 75 public String description() { 76 return drink.description(); 77 } 78 79 /* (non-Javadoc) 80 * <p>Title: cost</p> 81 * <p>Description: </p> 82 * @return 83 * @see decoratorDemo.Drink#cost() 84 */ 85 @Override 86 public float cost() { 87 return drink.cost(); 88 } 89 90 } 91 92 93 package decoratorDemo; 94 95 /** 96 * @ClassName: SugarDecorator 97 * @Description: 具体的装饰者对象:糖 98 * @date 2015年2月5日 下午9:35:35 99 */ 100 public class SugarDecorator extends Decorator{ 101 102 /** 103 * @Title: SugarDecorator 104 * @Description: TODO 105 * @param drink 106 */ 107 public SugarDecorator(Drink drink) { 108 super(drink); 109 } 110 111 public String description(){ 112 return super.description()+"+糖"; 113 } 114 115 public float cost(){ 116 return super.cost()+0.5f; 117 } 118 119 } 120 121 122 package decoratorDemo; 123 124 125 /** 126 * @ClassName: BlackBeanDecorator 127 * @Description: 具体的装饰者对象:黑豆 128 * @date 2015年2月5日 下午9:39:34 129 */ 130 public class BlackBeanDecorator extends Decorator{ 131 132 /** 133 * @Title: BlackBeanDecorator 134 * @Description: TODO 135 * @param drink 136 */ 137 public BlackBeanDecorator(Drink drink) { 138 super(drink); 139 } 140 141 public String description(){ 142 return super.description()+"+黑豆"; 143 } 144 145 public float cost(){ 146 return super.cost()+3.0f; 147 } 148 149 } 150 151 152 package decoratorDemo; 153 154 /** 155 * @ClassName: EggDecorator 156 * @Description: 具体装饰者对象:鸡蛋 157 * @date 2015年2月5日 下午9:44:01 158 */ 159 public class EggDecorator extends Decorator{ 160 161 /** 162 * @Title: EggDecorator 163 * @Description: TODO 164 * @param drink 165 */ 166 public EggDecorator(Drink drink) { 167 super(drink); 168 } 169 170 public String description(){ 171 return super.description()+"+鸡蛋"; 172 } 173 174 public float cost(){ 175 return super.cost()+2.0f; 176 } 177 178 179 } 180 181 182 package decoratorDemo; 183 184 /** 185 * @ClassName: Test 186 * @Description: 测试 187 * @date 2015年2月5日 下午9:46:59 188 */ 189 public class Test { 190 191 /** 192 * @Title: main 193 * @Description: TODO 194 * @param args 195 * @return void 196 */ 197 public static void main(String[] args) { 198 199 //生产一杯豆浆 200 Drink soya = new SoyaBeanMilk(); 201 //在豆浆中加鸡蛋 202 EggDecorator eggSoya = new EggDecorator(soya); 203 //在加了鸡蛋的豆浆中加糖 204 SugarDecorator sugarEggSoya = new SugarDecorator(eggSoya); 205 //在加了糖的豆浆中加黑豆 206 BlackBeanDecorator blackBeanSugarEggSoya = new BlackBeanDecorator(sugarEggSoya); 207 208 //结账 209 System.out.println("你点的是:"+blackBeanSugarEggSoya.description()); 210 System.out.println("一共:"+blackBeanSugarEggSoya.cost()+"元"); 211 } 212 213 }
9.观察者模式
观察者模式定义:简单地说,观察者模式定义了一个一对多的依赖关系,让一个或多个观察者对象观察一个主题对象。
这样一个主题对象在状态上的变化能够通过所有的依赖于此对象的那些观察者对象,使这些观察者对象能够自动更新。
Subject( 被观察的对象接口)
-规定ConcreteSubject的统一接口;
-每个Subject可以有多个Observer;
ConcreteSubject(具体被观察对象)
-维护对所有具体观察者的引用的列表;
-状态变化时会发送通知给所有注册的观察者。
Observer(观察者接口)
-规定ConcreteObserver的统一接口;
-定义了一个update()方法;
ConcreteObserver(具体观察者)
-维护一个对ConcreteSubject的引用;
-特定状态与ConcreteSubject同步;
-实现Observer接口,通过update()方法接收ConcreteSubject的通知。
示例代码:
1 /** 2 * @Title: Subject.java 3 * @Package observer 4 * @Description: TODO 5 * @date 2015年2月23日 上午10:09:19 6 * @version V1.0 7 */ 8 package observer; 9 10 /** 11 * @ClassName: Subject 12 * @Description: 被观察者接口 13 * @date 2015年2月23日 上午10:09:19 14 */ 15 public interface Subject { 16 17 /** 18 * @Title: registerObserver 19 * @Description: 注册为一个观察者 20 * @param o 21 * @return void 22 */ 23 public void registerObserver(Observer o); 24 25 /** 26 * @Title: removeObserver 27 * @Description: 取消观察者 28 * @param o 29 * @return void 30 */ 31 public void removeObserver(Observer o); 32 33 /** 34 * @Title: notifyObserver 35 * @Description: 通知所有观察者更新信息 36 * @return void 37 */ 38 public void notifyObservers(); 39 40 } 41 42 /** 43 * @Title: Observer.java 44 * @Package observer 45 * @Description: TODO 46 * @date 2015年2月23日 上午10:13:40 47 * @version V1.0 48 */ 49 package observer; 50 51 /** 52 * @ClassName: Observer 53 * @Description: TODO 54 * @date 2015年2月23日 上午10:13:40 55 */ 56 public interface Observer { 57 58 /** 59 * @Title: update 60 * @Description: 观察者更新信息方法 61 * @param price 62 * @return void 63 */ 64 public void update(float price); 65 66 } 67 68 /** 69 * @Title: Doll.java 70 * @Package observer 71 * @Description: TODO 72 * @date 2015年2月23日 上午10:17:18 73 * @version V1.0 74 */ 75 package observer; 76 77 import java.util.Vector; 78 79 /** 80 * @ClassName: Doll 81 * @Description: 具体的被观察者对象:娃娃 82 * @date 2015年2月23日 上午10:17:18 83 */ 84 public class Doll implements Subject { 85 86 87 /** 88 * @Fields v : 被观察者维护的一个观察者对象列表 89 */ 90 private Vector<Observer> v = new Vector<Observer>(); 91 92 /** 93 * @Fields price : 价格 94 */ 95 private float price; 96 97 public float getPrice(){ 98 return price; 99 } 100 101 /** 102 * @Title: setPrice 103 * @Description: 修改价格时,通知所有观察者 104 * @param price 105 * @return void 106 */ 107 public void setPrice(float price){ 108 this.price = price; 109 notifyObservers(); 110 } 111 112 /** 113 * @Title: Doll 114 * @Description: TODO 115 * @param price 116 */ 117 public Doll(float price) { 118 super(); 119 this.price = price; 120 } 121 122 /** 123 * @Title: Doll 124 * @Description: TODO 125 */ 126 public Doll() { 127 super(); 128 } 129 130 /* (non-Javadoc) 131 * <p>Title: registerObserver</p> 132 * <p>Description: </p> 133 * @param o 134 * @see observer.Subject#registerObserver(observer.Observer) 135 */ 136 @Override 137 public void registerObserver(Observer o) { 138 //注册观察者 139 v.add(o); 140 141 } 142 143 /* (non-Javadoc) 144 * <p>Title: removeObserver</p> 145 * <p>Description: </p> 146 * @param o 147 * @see observer.Subject#removeObserver(observer.Observer) 148 */ 149 @Override 150 public void removeObserver(Observer o) { 151 //取消观察者 152 v.remove(o); 153 154 } 155 156 /* (non-Javadoc) 157 * <p>Title: notifyObserver</p> 158 * <p>Description: </p> 159 * @see observer.Subject#notifyObserver() 160 */ 161 @Override 162 public void notifyObservers() { 163 //实现通知所有的观察者对象 164 for (Observer o:v){ 165 o.update(price); 166 } 167 168 } 169 170 } 171 172 /** 173 * @Title: Person.java 174 * @Package observer 175 * @Description: TODO 176 * @date 2015年2月23日 上午10:29:39 177 * @version V1.0 178 */ 179 package observer; 180 181 /** 182 * @ClassName: Person 183 * @Description: 具体的观察者对象 184 * @author 欧其平 185 * @date 2015年2月23日 上午10:29:39 186 */ 187 public class Person implements Observer{ 188 189 private String name; 190 191 public Person(String name){ 192 this.name = name; 193 } 194 195 /* (non-Javadoc) 196 * <p>Title: update</p> 197 * <p>Description: </p> 198 * @param price 199 * @see observer.Observer#update(float) 200 */ 201 @Override 202 public void update(float price) { 203 204 System.out.println(name+"关注的娃娃的价格已更新为:"+price); 205 206 } 207 208 } 209 210 /** 211 * @Title: Main.java 212 * @Package observer 213 * @Description: TODO 214 * @date 2015年2月23日 上午10:35:19 215 * @version V1.0 216 */ 217 package observer; 218 219 /** 220 * @ClassName: Main 221 * @Description: TODO 222 * @date 2015年2月23日 上午10:35:19 223 */ 224 public class Main { 225 226 /** 227 * @Title: main 228 * @Description: TODO 229 * @param args 230 * @return void 231 */ 232 public static void main(String[] args) { 233 234 //创建一个被观察者对象 235 Doll doll = new Doll(3000); 236 Person p1 = new Person("小白"); 237 Person p2 = new Person("小黑"); 238 //注册成为一个观察者 239 doll.registerObserver(p1); 240 doll.registerObserver(p2); 241 System.out.println("第一次降价:"); 242 //价格变动 243 doll.setPrice(2698); 244 System.out.println("第二次降价:"); 245 //价格变动 246 doll.setPrice(2299); 247 System.out.println("第三次降价:"); 248 //价格变动 249 doll.setPrice(1998); 250 251 doll.removeObserver(p2); 252 System.out.println("第四次降价:"); 253 //价格变动 254 doll.setPrice(1098); 255 } 256 257 }