[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.简单工厂模式
简单工厂模式:由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单使用的模式。
例如:
public class FactoryDemo { public static void main(String[] args) { Doll clothDoll = DollFactory.getInstance("cloth");
if(clothDoll != null){
System.out.println(clothDoll.getInfo());
}
Doll barbieDoll = DollFactory.getInstance("barbie");
if(barbieDoll != null){
System.out.println(barbieDoll.getInfo());
} } } /**
* @ClassName: DollFactory
* @Description: 工厂类
* @date 2015年1月16日 上午11:03:18
*/
class DollFactory{
//值负责产生对象
public static Doll getInstance (String name){
//根据条件不同的对象
if("cloth".equals(name)){
return new ClothDoll();
}else if ("barbie".equals(name)){
return new BarbieDoll();
}
return null;
} } /**
* @ClassName: Doll
* @Description: 娃娃类
* @date 2015年1月16日 上午11:03:13
*/
interface Doll{ public String getInfo();
} /**
* @ClassName: ClothDoll
* @Description: 布娃娃
* @date 2015年1月16日 上午11:03:09
*/
class ClothDoll implements Doll{ public String getInfo(){
return "我是布娃娃。";
}
} /**
* @ClassName: BarbieDoll
* @Description: 芭比娃娃
* @date 2015年1月16日 上午11:03:03
*/
class BarbieDoll implements Doll{ public String getInfo(){
return "我是芭比娃娃.";
}
}
FactoryDemo Code
5.代理设计模式
代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。代理模式说白了就是“真实对象”的代表,在
访问对象时引入一定程度的间接性,因为这种间接性可以附件多种用途。
静态代理:
/**
* @Title: ProxyDemo.java
* @Package proxydemo
* @Description: TODO
* @date 2015年1月16日 下午7:33:00
* @version V1.0
*/
package proxydemo; /**
* @ClassName: ProxyDemo
* @Description: 代理模式:为其他对象提供一种代理以控制对这个对象的访问。
* @date 2015年1月16日 下午7:33:00
*/
public class ProxyDemo { /**
* @Title: main
* @Description: TODO
* @param args
* @return void
*/
public static void main(String[] args) { Person p = new Person("小白");
//创建代理对象,并把代理对象传进来
Matchmaker m = new Matchmaker(p); m.miai();//相亲
} } /**
* @ClassName: Subject
* @Description: 主题接口
* @date 2015年1月16日 下午7:37:46
*/
interface Subject{ public void miai(); } /**
* @ClassName: Person
* @Description: 被代理类
* @date 2015年1月16日 下午7:37:25
*/
class Person implements Subject{ private String name; public Person(String name){
this.name = name;
} public void miai(){
System.out.println(name+"正在相亲中。。。");
} } /**
* @ClassName: Matchamker
* @Description: 代理类
* @date 2015年1月16日 下午7:36:58
*/
class Matchmaker implements Subject{ private Subject target;//要代理的目标对象 public Matchmaker(Subject target){
this.target = target;
} //相亲之前要做的事情
private void before(){
System.out.println("为代理人匹配如意郎君。");
} //相亲之后要做的事情
private void after(){
System.out.println("本次相亲结束。");
} //相亲方法
public void miai(){
before();
//真正执行相亲方法
target.miai();
after();
}
}
ProxyDemo Code
动态代理:Proxy的代理,接口和实现类之间可以不直接发生联系,而可以再运行期(Runtime)实现动态关联。
/**
* @Title: Subject.java
* @Package dynaproxy
* @Description: TODO
* @date 2015年2月23日 下午8:37:49
* @version V1.0
*/
package dynaproxy; /**
* @ClassName: Subject
* @Description: 要代理的主题接口
* @date 2015年2月23日 下午8:37:49
*/
public interface Subject { /**
* @Title: miai
* @Description: 相亲
* @return void
*/
public void miai(); } /**
* @Title: Person.java
* @Package dynaproxy
* @Description: TODO
* @date 2015年2月23日 下午8:39:12
* @version V1.0
*/
package dynaproxy; /**
* @ClassName: Person
* @Description: TODO
* @date 2015年2月23日 下午8:39:12
*/
public class Person implements Subject{ private String name; public Person(String name){
this.name = name;
} /* (non-Javadoc)
* <p>Title: miai</p>
* <p>Description: </p>
* @see dynaproxy.Subject#miai()
*/
@Override
public void miai() { System.out.println(name+"正在相亲中。。"); } } /**
* @Title: DynaProxy.java
* @Package dynaproxy
* @Description: TODO
* @date 2015年2月23日 下午8:40:47
* @version V1.0
*/
package dynaproxy; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; /**
* @ClassName: DynaProxy
* @Description: 动态代理类
* @date 2015年2月23日 下午8:40:47
*/
public class DynaProxy implements InvocationHandler{ private Object target;
public DynaProxy(Object target){
this.target = target;
} /* (non-Javadoc)
* <p>Title: invoke</p>
* <p>Description: </p>
* @param proxy
* @param method
* @param args
* @return
* @throws Throwable
* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object obj = null;
before();
//正真调用业务方法
obj = method.invoke(target, args);
after();
return obj;
} /**
* @Title: after
* @Description: 相亲之后要做的事情
* @return void
*/ private void after() {
System.out.println("本次相亲结束。");
} /**
* @Title: before
* @Description: 相亲之前要做的事情
* @return void
*/ private void before() {
System.out.println("为代理人匹配如意郎君。");
} } /**
* @Title: Test.java
* @Package dynaproxy
* @Description: TODO
* @date 2015年2月23日 下午8:49:10
* @version V1.0
*/
package dynaproxy; import java.lang.reflect.Proxy; /**
* @ClassName: Test
* @Description: TODO
* @date 2015年2月23日 下午8:49:10
*/
public class Test { public static void main(String[] args) { Person p = new Person("小白");
DynaProxy dp = new DynaProxy(p); /*
* Proxy提供用于创建动态代理类和实例的静态方法,
* 它还是这些方法创建的所有动态代理类的超类。
*/
//动态生成代理对象(类加载器,被代理接口,InvocationHandler)
Subject s = (Subject) Proxy.newProxyInstance(p.getClass()
.getClassLoader(), p.getClass().getInterfaces(), dp);
s.miai();
} }
6.适配器模式
适配器模式(Adapter):将一个类的接口装换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一
起工作的那些类可以一起工作。
例如:
/**
* @Title: AdapterDemo.java
* @Package adapterdemo
* @Description: TODO
* @date 2015年1月16日 下午8:03:11
* @version V1.0
*/
package adapterdemo; /**
* @ClassName: AdapterDemo
* @Description: 适配器模式(Adapter):将一个类的接口装换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
* @date 2015年1月16日 下午8:03:11
*/
public class AdapterDemo { /**
* @Title: main
* @Description: TODO
* @param args
* @return void
*/
public static void main(String[] args) { PowerA powerA = new PowerAImpl();
start(powerA); PowerB powerB = new PowerBImpl();
//把powerB封装进适配器
PowerAAdapter pa = new PowerAAdapter(powerB);
start(pa); } //开始工作
public static void start(PowerA powerA){
powerA.insert();
} } /**
* @ClassName: PowerAAdapter
* @Description: 适配器类
* @date 2015年1月16日 下午8:31:59
*/
class PowerAAdapter implements PowerA{ private PowerB powerB;//要进行适配的接口 public PowerAAdapter(PowerB powerB){
this.powerB = powerB;
} public void insert(){
powerB.connect();
} } /**
* @ClassName: PowerA
* @Description: 电源A接口
* @date 2015年1月16日 下午8:05:11
*/
interface PowerA{ public void insert(); } /**
* @ClassName: PowerAImpl
* @Description: TODO
* @date 2015年1月16日 下午8:07:33
*/
class PowerAImpl implements PowerA{ public void insert(){
System.out.println("电源A接口插入,开始工作。");
} } /**
* @ClassName: PowerB
* @Description: 电源B接口
* @date 2015年1月16日 下午8:05:54
*/
interface PowerB{ public void connect(); } /**
* @ClassName: PowerBImpl
* @Description: TODO
* @date 2015年1月16日 下午8:08:49
*/
class PowerBImpl implements PowerB{ public void connect(){
System.out.println("电源B接口以连接,开始工作。");
} }
AdapterDemo Code
7.享元设计模式
享元设计模式(Flyweight Pattern):它使用共享对象,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似对象;
它适合用于当大量对象只是重复因而导致无法令人接受的使用大量内存。通常对象中的部分状态是可以分享的。常见做法是把
他们放在外部数据结构,当需要使用时再将他们传递给享元。
运用共享技术有效的支持大量细粒度的对象。
例如:Integrate在一个字节内的对象。
8.装饰者设计模式
装饰着设计模式(Decorator):动态地给对象添加一些额外的职责。就添加功能来说,Decorator模式相比生成子类更为灵活。
改模式以对客户透明的方式扩展对象的功能。
涉及角色:
1)抽象构件角色:定义一个抽象接口,来规范准备附加功能的类。
2)具体构件角色:将要被附加功能的类,实现抽象构件角色接口。
3)抽象装饰者角色:将有对具体构件角色的引用并定义与抽象构件角色一致的接口。
4)具体装饰角色:实现抽象装饰者角色,负责为具体构件添加额外功能。
示例代码:
package decoratorDemo; /**
* @ClassName: Drink
* @Description: 被装饰者对象接口
* @date 2015年2月5日 下午9:23:33
*/
public interface Drink { //饮料的描述
public String description(); //计算价格
public float cost(); } package decoratorDemo; /**
* @ClassName: SoyaBeanMilk
* @Description: 具体的被装饰者对象: 豆浆
* @date 2015年2月5日 下午9:26:13
*/
public class SoyaBeanMilk implements Drink{ /* (non-Javadoc)
* <p>Title: decription</p>
* <p>Description: </p>
* @return
* @see decoratorDemo.Drink#decription()
*/
@Override
public String description() {
return "纯豆浆";
} /* (non-Javadoc)
* <p>Title: cost</p>
* <p>Description: </p>
* @return
* @see decoratorDemo.Drink#cost()
*/
@Override
public float cost() {
return 5f;
} } package decoratorDemo; /**
* @ClassName: Decorator
* @Description: 装饰者基类
* @date 2015年2月5日 下午9:29:37
*/
public abstract class Decorator implements Drink{ private Drink drink;//要装饰的对象 public Decorator(Drink drink){
this.drink = drink;
} /* (non-Javadoc)
* <p>Title: decription</p>
* <p>Description: </p>
* @return
* @see decoratorDemo.Drink#decription()
*/
@Override
public String description() {
return drink.description();
} /* (non-Javadoc)
* <p>Title: cost</p>
* <p>Description: </p>
* @return
* @see decoratorDemo.Drink#cost()
*/
@Override
public float cost() {
return drink.cost();
} } package decoratorDemo; /**
* @ClassName: SugarDecorator
* @Description: 具体的装饰者对象:糖
* @date 2015年2月5日 下午9:35:35
*/
public class SugarDecorator extends Decorator{ /**
* @Title: SugarDecorator
* @Description: TODO
* @param drink
*/
public SugarDecorator(Drink drink) {
super(drink);
} public String description(){
return super.description()+"+糖";
} public float cost(){
return super.cost()+0.5f;
} } package decoratorDemo; /**
* @ClassName: BlackBeanDecorator
* @Description: 具体的装饰者对象:黑豆
* @date 2015年2月5日 下午9:39:34
*/
public class BlackBeanDecorator extends Decorator{ /**
* @Title: BlackBeanDecorator
* @Description: TODO
* @param drink
*/
public BlackBeanDecorator(Drink drink) {
super(drink);
} public String description(){
return super.description()+"+黑豆";
} public float cost(){
return super.cost()+3.0f;
} } package decoratorDemo; /**
* @ClassName: EggDecorator
* @Description: 具体装饰者对象:鸡蛋
* @date 2015年2月5日 下午9:44:01
*/
public class EggDecorator extends Decorator{ /**
* @Title: EggDecorator
* @Description: TODO
* @param drink
*/
public EggDecorator(Drink drink) {
super(drink);
} public String description(){
return super.description()+"+鸡蛋";
} public float cost(){
return super.cost()+2.0f;
} } package decoratorDemo; /**
* @ClassName: Test
* @Description: 测试
* @date 2015年2月5日 下午9:46:59
*/
public class Test { /**
* @Title: main
* @Description: TODO
* @param args
* @return void
*/
public static void main(String[] args) { //生产一杯豆浆
Drink soya = new SoyaBeanMilk();
//在豆浆中加鸡蛋
EggDecorator eggSoya = new EggDecorator(soya);
//在加了鸡蛋的豆浆中加糖
SugarDecorator sugarEggSoya = new SugarDecorator(eggSoya);
//在加了糖的豆浆中加黑豆
BlackBeanDecorator blackBeanSugarEggSoya = new BlackBeanDecorator(sugarEggSoya); //结账
System.out.println("你点的是:"+blackBeanSugarEggSoya.description());
System.out.println("一共:"+blackBeanSugarEggSoya.cost()+"元");
} }
装饰者模式
9.观察者模式
观察者模式定义:简单地说,观察者模式定义了一个一对多的依赖关系,让一个或多个观察者对象观察一个主题对象。
这样一个主题对象在状态上的变化能够通过所有的依赖于此对象的那些观察者对象,使这些观察者对象能够自动更新。
Subject( 被观察的对象接口)
-规定ConcreteSubject的统一接口;
-每个Subject可以有多个Observer;
ConcreteSubject(具体被观察对象)
-维护对所有具体观察者的引用的列表;
-状态变化时会发送通知给所有注册的观察者。
Observer(观察者接口)
-规定ConcreteObserver的统一接口;
-定义了一个update()方法;
ConcreteObserver(具体观察者)
-维护一个对ConcreteSubject的引用;
-特定状态与ConcreteSubject同步;
-实现Observer接口,通过update()方法接收ConcreteSubject的通知。
示例代码:
/**
* @Title: Subject.java
* @Package observer
* @Description: TODO
* @date 2015年2月23日 上午10:09:19
* @version V1.0
*/
package observer; /**
* @ClassName: Subject
* @Description: 被观察者接口
* @date 2015年2月23日 上午10:09:19
*/
public interface Subject { /**
* @Title: registerObserver
* @Description: 注册为一个观察者
* @param o
* @return void
*/
public void registerObserver(Observer o); /**
* @Title: removeObserver
* @Description: 取消观察者
* @param o
* @return void
*/
public void removeObserver(Observer o); /**
* @Title: notifyObserver
* @Description: 通知所有观察者更新信息
* @return void
*/
public void notifyObservers(); } /**
* @Title: Observer.java
* @Package observer
* @Description: TODO
* @date 2015年2月23日 上午10:13:40
* @version V1.0
*/
package observer; /**
* @ClassName: Observer
* @Description: TODO
* @date 2015年2月23日 上午10:13:40
*/
public interface Observer { /**
* @Title: update
* @Description: 观察者更新信息方法
* @param price
* @return void
*/
public void update(float price); } /**
* @Title: Doll.java
* @Package observer
* @Description: TODO
* @date 2015年2月23日 上午10:17:18
* @version V1.0
*/
package observer; import java.util.Vector; /**
* @ClassName: Doll
* @Description: 具体的被观察者对象:娃娃
* @date 2015年2月23日 上午10:17:18
*/
public class Doll implements Subject { /**
* @Fields v : 被观察者维护的一个观察者对象列表
*/
private Vector<Observer> v = new Vector<Observer>(); /**
* @Fields price : 价格
*/
private float price; public float getPrice(){
return price;
} /**
* @Title: setPrice
* @Description: 修改价格时,通知所有观察者
* @param price
* @return void
*/
public void setPrice(float price){
this.price = price;
notifyObservers();
} /**
* @Title: Doll
* @Description: TODO
* @param price
*/
public Doll(float price) {
super();
this.price = price;
} /**
* @Title: Doll
* @Description: TODO
*/
public Doll() {
super();
} /* (non-Javadoc)
* <p>Title: registerObserver</p>
* <p>Description: </p>
* @param o
* @see observer.Subject#registerObserver(observer.Observer)
*/
@Override
public void registerObserver(Observer o) {
//注册观察者
v.add(o); } /* (non-Javadoc)
* <p>Title: removeObserver</p>
* <p>Description: </p>
* @param o
* @see observer.Subject#removeObserver(observer.Observer)
*/
@Override
public void removeObserver(Observer o) {
//取消观察者
v.remove(o); } /* (non-Javadoc)
* <p>Title: notifyObserver</p>
* <p>Description: </p>
* @see observer.Subject#notifyObserver()
*/
@Override
public void notifyObservers() {
//实现通知所有的观察者对象
for (Observer o:v){
o.update(price);
} } } /**
* @Title: Person.java
* @Package observer
* @Description: TODO
* @date 2015年2月23日 上午10:29:39
* @version V1.0
*/
package observer; /**
* @ClassName: Person
* @Description: 具体的观察者对象
* @author 欧其平
* @date 2015年2月23日 上午10:29:39
*/
public class Person implements Observer{ private String name; public Person(String name){
this.name = name;
} /* (non-Javadoc)
* <p>Title: update</p>
* <p>Description: </p>
* @param price
* @see observer.Observer#update(float)
*/
@Override
public void update(float price) { System.out.println(name+"关注的娃娃的价格已更新为:"+price); } } /**
* @Title: Main.java
* @Package observer
* @Description: TODO
* @date 2015年2月23日 上午10:35:19
* @version V1.0
*/
package observer; /**
* @ClassName: Main
* @Description: TODO
* @date 2015年2月23日 上午10:35:19
*/
public class Main { /**
* @Title: main
* @Description: TODO
* @param args
* @return void
*/
public static void main(String[] args) { //创建一个被观察者对象
Doll doll = new Doll(3000);
Person p1 = new Person("小白");
Person p2 = new Person("小黑");
//注册成为一个观察者
doll.registerObserver(p1);
doll.registerObserver(p2);
System.out.println("第一次降价:");
//价格变动
doll.setPrice(2698);
System.out.println("第二次降价:");
//价格变动
doll.setPrice(2299);
System.out.println("第三次降价:");
//价格变动
doll.setPrice(1998); doll.removeObserver(p2);
System.out.println("第四次降价:");
//价格变动
doll.setPrice(1098);
} }
最新文章
- IE7 浏览器下面设置text-indent属性变成margin属性BUG
- PLSQL note
- Code First开发系列之数据库迁移
- Android 学习路线图
- MySQL的Explain命令
- mint上部署lamp环境
- C语言实现strcmp
- java中如何忽略字符串中的转义字符--转载
- C++与Lua交互(一)
- 设置 ubuntu ftp
- 异常关闭MyEclipse 8.6后,不能重启
- 201521123012 《Java程序设计》第十三周学习总结
- Python——Django-__init__.py的内容
- 浅析 JavaScript 中的 Function.prototype.bind() 方法
- git 入门教程之知识速查
- python list和tuple
- P1019 单词接龙 字符串回溯
- 1.2.4注意Sysyem.out.println与i--
- 什么时候用var关键字
- CentOS6.5安装配置PPTP