您的位置:首页 > 编程语言 > Java开发

Java23种设计模式01

2013-04-12 07:59 363 查看

Java23种设计模式

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) {
this.name = name;
}

public String getName() {
return this.name;
}
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!");
}
}
Client

public cla*s Test {
public stati* void main(String[] args) {
Target target = new Adapter(new Adaptee());
tar*et.adapteeMethod();

target.adapterM*thod();
}
}
result

Adaptee method!
Adapter method!

1.2.2 桥接模式

将抽象部分与它*实现部分分离,使它们都可以独立地变化。

适用性

1.你不希望在抽*和它的实现部分之间有一个固定的绑定关系。

例如这种情况可能是因为,在程序运行时刻实现部分应可以*选择或者切换。

2.类的抽象以及它的实现都应该可以通*生成子类的方法加以扩充。

这时Bridge模式使你可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。

3.对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译。

4.正如在意图一节的第一个类图中所示的那样,有许多类要生成。

这*一种类层次结构说明你必须将一个对象分解成两个部分。

5.*想在多个对象间共享实现(可能使用引用计数),但同时要求客户并不知*这一点。

参与者

1.Abstraction

定义抽象类的接口。

维护一个指向Implementor类型对象的指针。

2.RefinedAbstraction

扩充由Abstraction定义的接口。

3.Implementor

定义实现类的接口,该接口不一定要与Ab*traction的接口完全一致。

事实上这两个接口可以完全不同。

*般来讲,Implementor接口仅提供基本操作,而Abstraction则定义了基于这些基本操作的较高层次的操作。

4.ConcreteImplementor

*现Implementor接口并定义它的具体实现。

类图

例子

Abstr*ction

public abstract class Person {
private Clothing clothing;

pr*vate String type;
public Clothing getClothing() {
return clothing;
}
publi* void setClothing() {
this.clothing = *lothingFactory.getClothing();
}

public void setType(String type) {
t*is.type = type;
}

public String getType() {
return this.ty*e;
}

public abstract void dress();
}
RefinedAbstraction

public class Man extends *erson {

public Man() {
setType("男人");
}

public void dress() {
Clothing clothing = get*lothing();
clothing.personDressCloth(this);
}
}
public class Lady extends Person {
public Lady() {
setTyp*("女人");
}

public void dress() {
Cloth*ng clothing = getClothing();
c*othing.personDressCloth(this);
}
}
Implemento*

public abstract class Clothing {
public abstract void personDressC*oth(*erson person);
}
ConcreteImplemento*

public class *ack*t extends Clothing {
public void personDressCloth(Person person) {
System.out.println(person.getType() + "穿马甲");
}
}
public cl*ss Trouser extends Clothing {
public void personDressCloth(Person person) {
System.ou*.println(*erson.getType() + "穿裤子");
}
}
Test

public class Te*t {
public s*atic void main(String[] args) {

Person man = new Man();

Person lady = new Lady();

Clothing jacket = new Ja*ket();

Clot*ing trouser = new Trouser();

jacket.personDressCloth(man);
trouser.personDressCloth(man);
j*cket.personDressCloth(lady);
trouser.personDressCloth(lady);
}
}
result

男人穿马甲
男人穿裤子
女人穿马甲
女人穿裤子

1.2.3 组合模式

将对象组合成树形结构以表示"部分-整体"的层次结构。"Composite使得用户对单个对象和组合对*的使用具有一致性。"

适用性

1.你想表示对象的部分-整*层次结构。

2.你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

参与者

1.Component

为组合中的对象声明接口。

在适当的情况下,实现所有类共有接口的缺省行为。

声明一个接口用于访问和管理Component的子组件。

(可选)在递归结构中定义一个接口,用于访问一个父部件,并在合*的情况下实现它。

2.Leaf

在组合中表示叶节点对象,叶节点没有子节点。

在组合中定义节点对象的行为。

3.Compos*te

定义有子部件的*些部件的行为。

存储子部件。

在Component接口中实现与子部件有*的操作。

4.Client

通过Component接*操纵组合部件的对象。

类图

例子

Component

p*blic abstract class Employer {
private String name;

public void setName(String name) {
this.name = *ame;
}

public String getName() {
return this.name;
}

public abstract void add(Employer employer*;

public abstract void delete(Employer employer);

public List employers;

public void printInfo*) {
System.out.println(name);
}

*ublic List getE*ployers() {
return this.employers;
}
}
Leaf

public class Programmer extends Employer {
public Programmer(String name) {
setNam*(name);
employers = null;//程序员, 表示没有下属了
}
public v*id add(Employer employer) {

}
public void delete(Employer employer) {

}
}
public class Pro*ectAssistant extends Employer {
public ProjectAss*stant(String name) {
setName(name);
employers = *ull;//项目助理, 表示没有下属了
}
public void add(Employer employer) {

}
public void delet*(Employer employer) {

}
}
Composite

public class Project*anager extends E*ployer {

public ProjectManager(String name) {
setName(name);
employers = new A*rayList();
}

public void add(Employer employer) {
employers.add(employer);
}
public void delete(Emplo*er employer) {
employers.remove(employer);
}
}
Clie*t

publ*c class Test {
public st*tic void main(String[] args) {
Employer pm = new ProjectManager("项目经理");
Emplo*er pa = new ProjectAssistant("项目助理");
Employer progra*mer1 = new Programmer("程序员一");
Employer programmer2 = new Programmer("程序员二");

pm.add(pa);//为项目经理添加项目助理
pm.add(programmer2);//*项目经理*加程序员

List ems = pm.getEm*loyers();
for (Employer em : ems) {
System.out.println(em.getNam*());
}
*
}
result

项目助理
程序员二

1.2.4 装饰模式

动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模*相比生成子类更为*活。

适用性

1.在不影响其他*象的情况下,以动态、透明的方式给单个对象添加职责。

2.处理那些可以撤消的职责。

3.当不能采用生成子类的方法进行扩充时。

参与者

1.Component

定义一个对象接口,可以给这些对象动态地添加职责。

2.ConcreteComponent

定义一个对象,可以给这个对象添加一些职责。

3.Decorator

维持一个指向Component对象的指针,并定义一个与Component接口一致的接口。

4.ConcreteDecorator

向组件添加职责。

类图

例子

Component

public interface Person {
void eat();
}
ConcreteComponent

*ublic class M*n implements Person {
public void eat() {
System.out.println("男人在吃");
*
}
Decorator

public abstrac* class Decorator implements Perso* {
protected Person person*

public void setPerson(Person person) {
this.person = person;
}

public void eat() {
person.eat();
}
}
ConcreteDec*rator

publi* class ManDecoratorA extends Decorator {
public void eat() {
super.eat();
reEat();
Sy*tem.out.println("ManDecoratorA类");
}
public void reEat() {
System.out.println("再吃一顿饭");
*
}
public class ManDecoratorB extends Decorator *

public void eat() {
super.eat();
Syst*m.out.println("===============");
System.out.println("ManDecoratorB类");
}
}
Test

public class Test {
public st*tic void main(Strin*[] args) {
Man man = new Man();
ManDecoratorA md1 = new ManDecoratorA();
ManDecoratorB md2 = n*w ManDecoratorB();

md1.setPerson(man);
md2.setPerson(md1);
md2.eat();
}
}
result

男人在吃
再吃一顿饭
ManDecoratorA类
===============
ManDecoratorB类
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: