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

常用设计模式

2015-07-29 06:53 806 查看
单例模式:

单态模式

保证一个类仅有一个实例,只提供一个访问它的全局访问点。

适用性

1.当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。

2.当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。

参与者

Singleton 定义一个Instance操作,允许客户访问它的唯一实例。Instance是一个类操作。 可能负责创建它自己的唯一实例。

例子

Singleton
public class Singleton

{

private static volatile Singleton instance = null;


public static Singleton getInstance()

{

if (instance == null)

{

synchronized (Singleton.class)

{

if (instance == null)

{

instance = new Singleton();

}

}

}

return instance;

}


private Singleton()

{


}


private Object readResolve()

{

return instance;

}


}

[/code]
public class TestDesignPattern

{


public static void main(String[] args)

{

Singleton sing = Singleton.getInstance();

Singleton sing2 = Singleton.getInstance();


System.out.println(sing);

System.out.println(sing2);


}


}

[/code]

result

com.kevin.test.instance.Singleton@74a14482

com.kevin.test.instance.Singleton@74a14482

工厂方法(FactoryMethod)

定义一个用于创建对象的接口,让子类决定实例化哪一个类。FactoryMethod使一个类的实例化延迟到其子类。

适用性

1.当一个类不知道它所必须创建的对象的类的时候。

2.当一个类希望由它的子类来指定它所创建的对象的时候。

3.当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。

参与者

1.Product 定义工厂方法所创建的对象的接口。

2.ConcreteProduct 实现Product接口。

3.Creator 声明工厂方法,该方法返回一个Product类型的对象* Creator也可以定义一个工厂方法的缺省实现,它返回一个缺省的 ConcreteProduct对象。 可以调用工厂方法以创建一个Product对象。

4.ConcreteCreator 重定义工厂方法以返回一个ConcreteProduct实例。

类图:





《Java与模式》中的图:



public interface Work {


void doWork();

}

[/code]

public class StudentWork implements Work {


public void doWork() {

System.out.println("学生做作业!");

}


}


public class TeacherWork implements Work {


public void doWork() {

System.out.println("老师审批作业!");

}

}

[/code]
public interface IWorkFactory {


Work getWork();

}


[/code]
public class StudentWorkFactory implements IWorkFactory {

public Work getWork() {

return new StudentWork();

}

}


public class TeacherWorkFactory implements IWorkFactory {

public Work getWork() {

return new TeacherWork();

}

}

[/code]

public class Test{

public static void main(String[] args) {

IWorkFactory studentWorkFactory = new StudentWorkFactory();

studentWorkFactory.getWork().doWork();


IWorkFactory teacherWorkFactory = new TeacherWorkFactory();

teacherWorkFactory.getWork().doWork();

}

}

[/code]

结果:

学生做作业!

老师审批作业!

形象比喻:

FACTORY METHOD—请MM去麦当劳吃汉堡,不同的MM有不同的口味,要每个都记住是一件烦人的事情,我一般采用Factory Method模式,带着MM到服务员那儿,说“要一个汉堡”,具体要什么样的汉堡呢,让MM直接跟服务员说就行了。

工厂方法模式:核心工厂类不再负责所有产品的创建,而是将具体创建的工作交给子类去做,成为一个抽象工厂角色,仅负责给出具体工厂类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。

抽象工厂(AbstractFactory)

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

适用性

1.一个系统要独立于它的产品的创建、组合和表示时。

2.一个系统要由多个产品系列中的一个来配置时。

​3.当你要强调一系列相关的产品对象的设计以便进行联合使用时。

​4.当你提供一个产品类库,而只想显示它们的接口而不是实现时。

参与者

​1.AbstractFactory 声明一个创建抽象产品对象的操作接口。

​2.ConcreteFactory 实现创建具体产品对象的操作。

​3.AbstractProduct为一类产品对象声明一个接口。

​4.ConcreteProduct 定义一个将被相应的具体工厂创建的产品*象。 实现abstractProduct接口。

​5.Client仅使用由AbstractFactory和AbstractProduct类声明的接口



​类图



《Java与模式》中的图:



例子

abstractFactory


public interface IAnimalFactory {


ICat createCat();


IDog createDog();

}


ConcreteFactory


public class BlackAnimalFactory implements IAnimalFactory {


public ICat createCat() {

return new BlackCat();

}


public IDog createDog() {

return new BlackDog();

}


}


public class WhiteAnimalFactory implements IAnimalFactory {


public ICat createCat() {

return new WhiteCat();

}


public IDog createDog() {

return new WhiteDog();

}


}

AbstractProduct


public interface ICat {


void eat();

}


public interface IDog {


void eat();

}

Concreteproduct


public class BlackCat implements ICat {


public void eat() {

System.out.println("The black cat is eating!");

}

}

public class WhiteCat implements ICat {


public void eat() {

System.out.println("The white 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 eating!");

}


}

Client


public static void main(String[] args) {

IAnimalFactory blackAnimalFactory = new BlackAnimalFactory();

ICat blackCat = blackAnimalFactory.createCat();

blackCat.eat();

IDog blackDog = blackAnimalFactory.createDog();

blackDog.eat();


IAnimalFactory whiteAnimalFactory = new WhiteAnimalFactory();

ICat whiteCat = whiteAnimalFactory.createCat();

whiteCat.eat();

IDog whiteDog = whiteAnimalFactory.createDog();

whiteDog.eat();

}

result


The black cat is eating!

The black dog is eating!

The white cat is eating!

The white dog is eating!

[/code]

形象比喻:

ABSTRACT FACTORY—追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说“来四个鸡翅”就行了。麦当劳和肯德基就是生产鸡翅的Factory

工厂模式:客户类和工厂类分开。消费者任何时候需要某种产品,只需向工厂请求即可。消费者无须修改就可以接纳新产品。缺点是当产品修改时,工厂类也要做相应的修改。如:如何创建及如何向客户端提供。

建造者模式(Builder)

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

适用性

1.当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。2.当构造过程必须允许被构造的对象有不同的表示时。

参与者

1.Builder 为创建一个Product对象的各个部件指定抽象接口。

2.ConcreteBuilder 实现Builder的接口以构造和装配该产品的各个部件。 定义并明确它所创建的表示。 提供一个检索产品的接口。

3.Director 构造一个使用Builder接口的对象。

4.Product 表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程。 包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

Android 中dialog的创建用到了建造器模式。

类图




public interface PersonBuilder {


void buildHead();


void buildBody();


void buildFoot();


Person buildPerson();

}

ConcreteBuilder


public class ManBuilder implements PersonBuilder {


Person person;


public ManBuilder() {

person = new Man();

}


public void buildbody() {

person.setBody("建造男人的身体");

}


public void buildFoot() {

person.setFoot("建造男人的脚");

}


public void buildHead() {

person.setHead("建造男人的头");

}


public Person buildPerson() {

return person;

}

}

Director


public class PersonDirector{

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 getHead() {

return head;

}

public void setHead(String head) {

this.head = head;

}

public String getBody() {

return body;

}

public void setBody(String body) {

this.body = body;

}

public String getFoot() {

return foot;

}

public void setFoot(String foot) {

this.foot = foot;

}

}


public class Man extends Person {


}

Test


public class Test{


public static void main(String[] args) {

PersonDirectorpd = new PersonDirector();

Person person = pd.constructPerson(new ManBuilder());

System.out.println(person.getBody());

System.out.println(person.getFoot());

System.out.println(person.getHead());

}

}

[/code]

组合模式(Composite)

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

适用性

1.你想表示对象的部分-整体层次结构。 2.你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

参与者

1.Component 为组合中的对象声明接口。 在适当的情况下,实现所有类共有接口的缺省行为。 声明一个接口用于访问和管理Component的子组件。 (可选)在递归结构中定义一个接口,用于访问一个父部件,并在合*的情况下实现它。 2.Leaf 在组合中表示叶节点对象,叶节点没有子节点。 在组合中定义节点对象的行为。 3.Composite 定义有子部件的*些部件的行为。 存储子部件。 在Component接口中实现与子部件有*的操作。
4.Client通过Component接口操纵组合部件的对象。

类图(另外找的)




public abstract class Employer {


private String name;


public void setName(String name) {

this.name = name;

}


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);

}


public List getEmployers() {

return this.employers;

}

}

Leaf


public class Programmer extends Employer {


public Programmer(String name) {

setName(name);

employers = null;//程序员, 表示没有下属了

}


public void add(Employer employer) {


}


public void delete(Employer employer) {


}

}


public class ProjectAssistant extends Employer {


public ProjectAssistant(String name) {

setName(name);

employers = null;//项目助理, 表示没有下属了

}


public void add(Employer employer) {


}


public void delete(Employer employer) {


}

}

Composite


public class ProjectManager extends Employer {


public ProjectManager(String name) {

setName(name);

employers = new ArrayList();

}


public void add(Employer employer) {

employers.add(employer);

}


public void delete(Employer employer) {

employers.remove(employer);

}

}

Client


public class Test{


public static void main(String[] args) {

Employer pm = new ProjectManager("项目经理");

Employer pa = new ProjectAssistant("项目助理");

Employer programmer1 = new Programmer("程序员一");

Employer programmer2 = new Programmer("程序员二");


pm.add(pa);//为项目经理添加项目助理

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


List ems = pm.getEmployers();

for (Employer em : ems) {

System.out.println(em.getName());

}

}

}

[/code]

形象比喻:

COMPOSITE—Mary今天过生日。“我过生日,你要送我一件礼物。”“嗯,好吧,去商店,你自己挑。”“这件T恤挺漂亮,买,这条裙子好看,买,这个包也不错,买。”“喂,买了三件了呀,我只答应送一件礼物的哦。”“什么呀,T恤加裙子加包包,正好配成一套呀,小姐,麻烦你包起来。 ”“……”,MM都会用Composite模式了,你会了没有?

合成模式:合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。合成模式就是一个处理对象的树结构的模式。合成模式把部分与整体的关系用树结构表示出来。合成模式使得客户端把一个个单独的成分对象和由他们复合而成的合成对象同等看待。

观察者模式(Observer)

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

适用性

1.当一个抽象模型有两个方面,其中一个方面依赖于另一方面。 将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。

2.当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。

3.当一个对象必须通知其它对象,而它又不能假定其它对象是谁。

参与者

1.Subject(目标) 目标知道它的观察者。可以有任意多个观察者观察同一个目标。 提供注册和删除观察者对象的接口。

2.Observer(观察者) 为那些在目标发生改变时需获得通知的对象定义一个更新接口。

3.ConcreteSubject(具体目标) 将有关状态存入各ConcreteObserver对象。 当它的状态发生改变时,向它的各个观察者发出通知。

4.ConcreteObserver(具体观察者) 维护一个指向ConcreteSubject对象的引用。 存储有关状态,这些状态应与目标的状态保持一致。 实现Observer的更新接口*使自身状态与目标的状态保持一致


public abstract class Citizen {


List pols;


String help = "normal";


public void setHelp(String help) {

this.help = help;

}


public String getHelp() {

return this.help;

}


abstract void sendMessage(String help);


public void setPolicemen() {

this.pols = new ArrayList();

}


public void register(policeman pol) {

this.pols.add(pol);

}


public void unRegister(Policeman pol) {

this.pols.remove(pol);

}

}

Observer


public interface Policeman {


void action(Citizen ci);

}

ConcreteSubject


public class HuangPuCitizen extends Citizen {


public HuangPuCitizen(Policeman pol) {

setPolicemen();

register(pol);

}


public void sendMessage(String help) {

setHelp(help);

for(int i = 0; i < pols.size(); i++) {

Policeman pol = pols.get(i);

//通知警察行动

pol.action(this);

}

}

}


public class TianHeCitizen extends Citizen {


public TianHeCitizen(Policeman pol) {

setPolicemen();

register(pol);

}


public void sendMessage(String help) {

setHelp(help);

for (int i = 0; i < pols.size(); i++) {

Policeman pol = pols.get(i);

//通知警察行动

pol.action(this);

}

}

}

ConcreteObserver


public class HuangPuPoliceman implements Policeman {


public void action(Citizen ci) {

String help = ci.getHelp();

if (help.equals("normal")) {

System.out.println("一切正常, 不用出动");

}

if (help.equals("unnormal")) {

System.out.println("有犯罪行为, 黄埔警察出动!");

}

}

}


public class TianHePoliceman implements Policeman {


public void action(Citizen ci) {

String help = ci.getHelp();

if (help.equals("normal")) {

System.out.println("一切正常, 不用出动");

}

if (help.equals("unnormal")) {

System.out.println("有犯罪行为, 天河警察出动!");

}

}

}

Test


public class Test{


public static void main(String[] args) {

Policeman thPol = new TianHePoliceman();

Policeman hpPol = new HuangPuPoliceman();


Citizen citizen = new HuangPuCitizen(hpPol);

citizen.sendMessage("unnormal");

citizen.sendMessage("normal");


System.out.println("===========");


citizen = new TianHeCitizen(thPol);

citizen.sendMessage("normal");

citizen.sendMessage("unnormal");

}

}

[/code]

适配器模式(Adapter)
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

适用性

1.你想使用一个已经存在的类,而它的接口不符合你的需求。

2.你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。

3.(仅适用于对象Adapter)你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。

参与者

1.Target 定义Client使用的与特定领域相关的接口。

2.Client与符合Target接口的对象协同。

3.Adaptee 定义一个已经存在的接口,这个接口需要适配。

4.Adapter 对Adaptee的接口与Target接口进行适配

类图



Target


public interface Target{


void adapteeMethod();


void adapterMethod();

}

Adaptee


public class Adaptee{


public void adapteeMethod() {

System.out.println("Adapteemethod!");

}

}

Adapter


public class Adapterimplements Target{


private Adapteeadaptee;


public Adapter(Adapteeadaptee) {

this.adaptee = adaptee;

}


public void adapteeMethod() {

adaptee.adapteeMethod();

}


public void adapterMethod() {

system.out.println("Adaptermethod!");

}

}

Client


public class Test{


public static void main(String[] args) {

Targettarget = new Adapter(new Adaptee());

target.adapteeMethod();


target.adapterMethod();

}

}

result


Adapteemethod!

Adaptermethod!

[/code]

形象比喻:

ADAPTER—在朋友聚会上碰到了一个美女Sarah,从香港来的,可我不会说粤语,她不会说普通话,只好求助于我的朋友kent了,他作为我和Sarah之间的Adapter,让我和Sarah可以相互交谈了(也不知道他会不会耍我)

  适配器(变压器)模式:把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口原因不匹配而无法一起工作的两个类能够一起工作。适配类可以根据参数返还一个合适的实例给客户端。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息