Java中23种设计模式
目录
1. 设计模式 ........................................................................................................................................ 2
1.1 创建型模式 .......................................................................................................................... 2
1.1.1 工厂方法 ................................................................................................................... 2 1.1.2 抽象工厂 ................................................................................................................... 4 1.1.3 建造者模式 ............................................................................................................... 8 1.1.4 单态模式 ................................................................................................................. 11 1.1.5 原型模式 ................................................................................................................. 13 1.2 结构型模式 ........................................................................................................................ 15
1.2.1 适配器模式 ............................................................................................................. 15 1.2.2 桥接模式 ................................................................................................................. 17 1.2.3 组合模式 ................................................................................................................. 20 1.2.4 装饰模式 ................................................................................................................. 24 1.2.5 外观模式 ................................................................................................................. 26 1.2.6 享元模式 ................................................................................................................. 30 1.2.7 代理模式 ................................................................................................................. 32 1.3 行为型模式 ........................................................................................................................ 35
1.3.1 责任链模式 ............................................................................................................. 35 1.3.2 命令模式 ................................................................................................................. 38 1.3.3 解释器模式 ............................................................................................................. 41 1.3.4 迭代器模式 ............................................................................................................. 43 1.3.5 中介者模式 ............................................................................................................. 47 1.3.6 备忘录模式 ............................................................................................................. 50 1.3.7 观察者模式 ............................................................................................................. 52 1.3.8 状态模式 ................................................................................................................. 56 1.3.9 策略模式 ................................................................................................................. 59 1.3.10 模板方法 ............................................................................................................... 61 1.3.11 访问者模式 ........................................................................................................... 63
1. 设计模式(超级详细) 1.1 创建型模式
AbstractFactory ( 抽象工厂 ) FactoryMethod ( 工厂方法 ) Singleton ( 单态模式 ) Builder ( 建造者模式 ) Protot*pe * 原型模式 )
1.1.1 工厂方法
*义一个用于创建对象的接口,让子类决定实例化哪一个类。FactoryMethod使一个类的实例*延迟到其子类。
适用性
1.当一个类不知道它所必须创建的对象的类的时候。
2.当一个类希望由它的子类来指定它所创建的对象的时候。
3.当*将创建对象的职责委托给多个帮助*类中的某一个,并且*希望将哪一个帮助子类是代理者这一信息局部化的时候。
参与者
1.Product
定义工厂方法所创建的对象的接口。
2.ConcreteProduct 实现Product接口。
3.Creator
声明工厂方法,该方法返回一个Product类型的对象*
Creator也可以定义一个工厂方法的缺省实现,它返回一个缺省的ConcreteProduct对象。
可以调用工厂方法以创建一个Product对象。
4.ConcreteCreator
重定义工厂方法以返回一个ConcreteProduct实例。
类图
例子 *roduct
public interface Work {
void doWork(); }
ConcreteProduct
public class StudentWork implements Work {
public void doWork() {
System.out.println("学生*作业!"); } }
public class TeacherWork implements Work {
public void doWork() {
System.out.println("老师审批作业!"); } }
Creator
public interface IWorkFactory {
Work get*ork(); }
Concre*eCreator
pu*lic class StudentWorkFactory implements IWorkFactory {
public Work getWork() {
*eturn new StudentWork(); } }
public class TeacherWorkFactory implements IWorkFactory {
public Work getWork() {
return new TeacherWork(); } }
Test
public class Test {
public static void m*in(Strin*[] args) {
IWorkFactory studentWorkFactory = new StudentWorkFactory(); studentWorkFactory.getWork().d*Work();
IWorkFactory teacherWorkFactory * new TeacherWorkFactory(); teacherWorkFactory.g*tWork().*oWork();
} }
result
学生做作业! 老师审批作业!
1.1.2 抽象工厂
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
适用性
1.一个系统要独立于它的*品的创建、组合和表示时。
2.一个系统要由多个产品系列中的一个来配置时。
3.当你要强调一系列相关的产品对象的设计以便进行联合使用时*
4*当你提供一个产品类库,而只想显示它们*接口而不是实现时。
参与者
1.Ab*tractFactory
声明一个创建抽象产品对象的操作接口。
2.ConcreteFactory
实现创建具体产品对象的操作。
*.AbstractProduct
为一类产品对象声明一个接口。
4.ConcreteProdu*t
定义一个将被相应的具体工厂创建的产品*象。 实现*bstractProduct接口。
5.Client
仅使用由AbstractFactory和AbstractProduc*类声明的接口
类图
例子 *bstractFactory
public interface IAn*malFactory {
ICat createCat();
IDog cre*teDog();
ConcreteFactory
p*blic class BlackAnimalFactory implem*nts IAnimalFactory {
public ICat createCat() { retur* new BlackCat(); }
public IDog createDog() { return new BlackDog(); } }
public class WhiteAnimalFac*ory imp*ements IAnimalFactory {
public ICat createCat() { return new WhiteCat(); }
public IDog cre*teDog() { return new WhiteDog(); } }
Abstrac*Product
public interface ICat {
void eat(); }
public interface IDog {
void eat(); }
Concrete*roduct
public class Black*at implements ICat {
public void eat() {
System.out.println("The bl*ck cat is eating!"); }
}
public class WhiteCat implements *Cat {
public void eat() {
Sy*tem.out.prin*ln("The w*ite cat is eating!*); } }
public class BlackDog implements IDog {
public void eat() {
System.out.println("The black dog is eating"); } }
public class WhiteDog implements IDog {
public void eat() {
System.out.println("The white dog is eat*ng!"); } }
Client
public static void main(String[] args) {
IAnimalFactory blackAnimalFa*tory = new BlackAnimalFactory(); ICat blackCat = blackAnimalFactory.createCat(); blackCat.eat();
IDog blackD*g = blackAnimalFactory.createDog(); blackDog.eat();
IAnimalFactory whiteAnimalF*ctory = new WhiteAnimalFactory(); ICat whiteCat = whiteAnimalFactory.createCat(); whiteCat.eat();
IDog *hiteDog = whiteAnimalFactory.createDog(); whiteDog.eat(); }
res*lt
The bla*k cat is eating!
Th* black dog is eatin*! The white cat is eating! The white dog is *ating!
1.1.3 建造者模式
将一个复杂对象的构*与它的表示分离,使*同样的构建过程可以创建不同的
表示。
适用性
1.当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
*.当构造过程必须允*被构造的对象有不同*表示时。
参与者
1.Builder
为创建一个Product对象的各个部件指定抽象接口。
2.ConcreteBuilder
实现Buil*er的接口以构造和装配该产品的各个部件。 定义并明确它所创建的表示* 提供一个检索产品的接口。
3.Director
构造一个使用Builder接口的对象。
4.Product
表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程。
包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
类图
例子 Buil*er
public interface PersonBuilder {
void buildHead();
v*id buildBody();
void buildFoot()*
Person buildPerson(); }
ConcreteBuilder
public class ManBuilder implements PersonB*ilder {
Person person;
public ManBuilder() { person = ne* Man(); }
publ*c void build*ody() {
perso*.setBody("建造男人的身体");
}
public void buildFoot() {
person.setFo*t("建造男人的脚"); }
public void buildHead() {
pers*n.setHead("建造*人的头"); }
*ublic Person buildPerson() { retur* person; } }
Dir*ctor
public class PersonDirec*or {
public Person constructPerson(PersonBuilder pb) { pb.buildHead(); pb.buildBody(); pb.buildFoot();
return pb.buildPerson(); } }
Product
public class Person {
private String head;
private String body;
private String foot;
public String getH*ad() { return head; }
public void setHead(String hea*) { this.head = head; }
public String getBody() {
return body; }
public void setBody(String body) { this.b*dy = body; }
public String getFoot() { return foot; }
public void setFoot(String foot) { t*is.foot = foot; } }
public class Man extends Person { }
Test
publ*c class Test{
public static void main(String[] ar*s) {
PersonDirector pd = new PersonDirector();
Person person = pd.constructPerson(new ManBuilder()); System*out.println(person.getBody()); System.out.println(person.getFoot());
System.out.println(person.getHead()); } }
result
建造男人*身体 建造男*的脚 建造男人的头
1.1.4 单态模式
保证一个类仅有一个实例,*提供一个访问它的全局访*点。
适用性
1.当类只能有一个*例而且客户可以从一个众所周知的访问点访问它时。
2.当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
参与者
Singleton
定义一个Instance操作,允许客户访问它的唯一实例。Instance是一个类操作。
可能负*创建它自己的唯一实例。
类图
例子 Singleton
public class Singleton {
private static Singleton sing;
private Singleton() { }
public st*tic Singleton get*nstance() { if (sing == null) {
sing = new Singleto*(); }
return sing; } }
Test
public class Test {
public static void *ain(*tring[] args) {
Singleton sing = Singleton.getInstance(); Singleton si*g2 = Singleton.getI*stance();
System.out.println(sing); System.out.pr*ntln(sing2); } }
result
singleton.Singleton@1c78e57 singleton.Singleton@1c78e57
1.1.5 原型模式
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
适用性
1.当一个系统应该独立于它的产品创*、构成和表示时。
2.当要实例化的类是在运行时刻指定时,例如,通过动态装载。
3.为了避免创建一个与产品类层次平行的工厂*层次时。
4.当一个类的实例只能有几个不同状态组合中的一种时。
建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。
参与者
1. Prototype
声明一个克隆自身的接口。
2. ConcretePrototype
实现一个克隆自身的操作。
3. Client
让一个原型克*自身从而创建一个新的对象。
类图
例子 Prototype
public class Prototype implements Cloneable {
private String name;
public void setName(String name) { http:// = name; }
public String getName() { return http://; }
public Object clone(){ try {
return super.clone(); } catch (Exception e) { e.printStackTrace(); return null; } } }
ConcretePrototype
publ*c class ConcretePrototype extend* Prototype {
public ConcretePrototype(String name) { setName(name); } }
Client
public clas* Test {
public static void main(String[] args) {
Prototype pro = new ConcretePrototy*e("prototype"); Prototype pro2 = (Prototype)pro.clone(); *ystem.out.println(pro.getName()*; System.out.println(pro2.getName()); } }
result
prototype
prototype
1.2 结构型模式
Adapter * 适配器模式 * Bridge ( 桥接模* ) Composite ( 组合模式 ) Decorator ( 装*模式 ) Facade ( 外观模式 ) Flyweight ( 享元模式 ) Proxy ( 代理模式 )
1.2.1 适配器模式
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口*兼容而不能一起工作的那*类可以一起工作。
适用性
1.你想使*一个已经存在的类,而它的接口不符合你的需求。
2.你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那*接口
可能不一定兼容的类)协同工作。
*.(仅适用于对象Adapter)你想使用一些已经存在的子类,但是不可能对每一个都进行
子类化以匹配它们的接口。对象适配器可以适配它的父类接口。
参与者
1.Target
定义Client使用的与特定领域相关的接口。
2.Client
与符合Target接口的对象协同。
3.Adapt*e
定义一个已经存在的接口,这个接口需要适配。
4.Adapter
对Adaptee的接口与Target接口进行适配
类图
例子 Target
public interface Target {
void adapteeMethod();
void adapterMethod(); }
Adaptee
public class Adaptee {
public void adapteeMethod() {
Syste*.out.p*intln("Adaptee method!"); } }
Adapt*r
public clas* Adapter implement* Target {
private Adap*ee adaptee;
public Adapter(Adaptee adaptee) { this.adapte* = adaptee; } public void adapteeMethod() { adaptee.adapteeMethod(); } public void adapterMethod() { *ystem.out.println("Adapter method!"); }