一、什么是软件设计模式?
设计模式:是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。
二、设计模式和框架
可复用面向对象软件系统现在一般划分为两大类:应用程序工具箱和框架(Framework),我们平时开发的具体软件都是应用程序,Java的API属于工具箱;而框架是构成一类特定软件可复用设计的一组相互协作的类,EJB(EnterpriseJavaBeans)是Java应用于企业计算的框架。
框架通常定义了应用体系的整体结构类和对象的关系等等设计参数,以便于具体应用实现者能集中精力于应用本身的特定细节。框架主要记录软件应用中共同的设计决策,框架强调设计复用,因此框架设计中必然要使用设计模式。
设计模式有助于对框架结构的理解,成熟的框架通常使用了多种设计模式,如果你熟悉这些设计模式,毫无疑问,你将迅速掌握框架的结构,我们一般开发者如果突然接触EJBJ2EE等框架,会觉得特别难学,难掌握,那么转而先掌握设计模式,无疑是给了你剖析EJB或J2EE系统的一把利器。设计模式使人们可以更加简单方便地复用成功的设计和体系结构。将已证实的技术表述成设计模式也会使新系统开发者更加容易理解其设计思路。
模式名称(pattern name) 一个助记名,它用一两个词来描述模式的问题、解决方案和效果。命名一个新的模式增加了我们的设计词汇。设计模式允许我们在较高的抽象层次上进行设计。基于一个模式词汇表,我们自己以及同事之间就可以讨论模式并在编写文档时使用它们。模式名可以帮助我们思考,便于我们与其他人交流设计思想及设计结果。找到恰当的模式名也是我们设计模式编目工作的难点之一。
问题(problem) 描述了应该在何时使用模式。它解释了设计问题和问题存在的前因后果,它可能描述了特定的设计问题,如怎样用对象表示算法等。也可能描述了导致不灵活设计的类或对象结构。有时候,问题部分会包括使用模式必须满足的一系列先决条件。
解决方案(solution) 描述了设计的组成成分,它们之间的相互关系及各自的职责和协作方式。因为模式就像一个模板,可应用于多种不同场合,所以解决方案并不描述一个特定而具体的设计或实现,而是提供设计问题的抽象描述和怎样用一个具有一般意义的元素组合(类或对象组合)来解决这个问题。
效果(consequences) 描述了模式应用的效果及使用模式应权衡的问题。尽管我们描述设计决策时,并不总提到模式效果,但它们对于评价设计选择和理解使用模式的代价及好处具有重要意义。软件效果大多关注对时间和空间的衡量,它们也表述了语言和实现问题。因为复用是面向对象设计的要素之一,所以模式效果包括它对系统的灵活性、扩充性或可移植性的影响,显式地列出这些效果对理解和评价这些模式很有帮助。
三、设计模式的原则是什么?
1、合成复用原则 :
就是说要少用继承,多用合成关系来实现。
2、依赖倒转原则 :
抽象不应该依赖于细节,细节应当依赖于抽象。
3、接口隔离原则
定制服务的例子,每一个接口应该是一种角色。
4、迪米特法则
最少知识原则。
四、设计模式总体分类
1、创建型模式
包括:工厂方法、抽象工厂、建造者模式、单例模式、原型模式;
2、结构型模式
包括:适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式、代理模式;
3、行为型模式
包括:责任模式、命令模式、解释器模式、迭代模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板模式、访问者模式。
五、举例说明:抽象工厂、适配器模式、命令模式
1、抽象工厂:提供一个创建系列相关或者依赖对象的接口,无需指定具体的类的一种模式。
抽象工厂的参与者:AbstractFactory:声明一个创建抽象产品对象的操作接口
ConcreateFactory:为一类产品对象声明一个接口;
AbstractProduct:为一类产品声明的一个接口
ConcreateProduct:定义一个将被相应的具体的工厂常见的产品对象
Client:仅适用由AbstractFactory和 AbstractProduct类声明的接口
举例:
AbstractFactory接口:
public interface AnimalFactory { Cat createCat(); Dog createDog(); }
ConcreateFactory:
public class BlackAnimalFactory implements AnimalFactory
{
public Cat createCat()
{
return new BlackCat();
}
public Dog createDog()
{
return new BlackDog();
}
}
public class WhiteAnimalFactory implements AnimalFactory
{
public Cat createCat()
{
return new WhiteCat();
}
public Dog createDog()
{
return new WhiteDog();
}
}
AbstractProduct:
public interface Cat
{
void eat();
}
public interface Dog
{
void eat();
}
ConcreateProduct:
public class BlackCat implements Cat
{
public void eat()
{
System.out.println("the black cat is eatting!");
}
}
public class WhiteCat implements Cat
{
public void eat()
{
System.out.println("the white cat is eatting!");
}
}
public class BlackDog implements Dog
{
public void eat()
{
System.out.println("the black dog is eatting!");
}
}
public class WhiteDog implements Dog
{
public void eat()
{
System.out.println("the white dog is eatting!");
}
}
Client:
public static void main(String []args)
{
AnimalFactroy blackAnimalFactory=new BlackAnimalFactory();
Cat blackCat=blackAnimalFactory.createCat();
blackCat.eat();
Dog blackDog=blackAnimalFactory.createDog();
blackDog.eat();
AnimalFactroy whiteAnimalFactory=new WhiteAnimalFactory();
Cat whiteCat=whiteAnimalFactory.createCat();
whiteCat.eat();
Dog whiteDog=whiteAnimalFactory.createDog();
whiteDog.eat();
}
考到上面这个例子,我们就可以清晰的明白什么叫抽象工厂模式了。如果再自己动手试一试就更好了。
2、适配器模式:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
适配器模式的参与者:
Target:定义client使用的与特定领域相关的接口
Cleint:与符合Target接口的对象的协同
Adaptee:定义一个已经存在的接口,这个接口需要适配
Adapter:对Adapter的接口与Targer接口进行适配
Targer:public interface Targer
{
void adapteeMethod();
void adapterMethod();
}
Adaptee:
public calss Adaptee
{
public void adapteeMethod()
{
System.out.println("Adaptee Method");
}
}
Adapter:
public class Adapter implements Targer
{
private Adaptee adaptee;
public Adapter(Adaptee adaptee)
{
this.adaptee=adaptee;
}
public void adapteeMethod()
{
adaptee.adapteeMethod();
}
public void adapterMethod()
{
System.out.println("Adapter Method!");
}
}
Client:
public class AdapterTest
{
public static void main(String []args)
{
Targer targer =new Adapter(new Adaptee());
targer.adapteeMethod();
targer.adapterMethod();
}
}
3、命令模式:将一个请求封装为一个对象,从而是你可用不同的请求对客户进行参数化,对请求排队或者记录请求的日记,以及支持可撤销的操作。
命令模式的参与者:
Command:声明执行操作的接口
ConcreateCommand:将一个接受者对象绑定与一个动作
Client:创建一个具体的命令对象并设定他的接收者
Invoker:要求改命令执行这个请求:
Receiver:如何实施与执行一个请求相关的操作,任何类都可以作为一个接受者。
Command:
public abstract class Command
{
protected Receiver receiver;
public Command (Receiver receiver)
{
this.receiver=receiver;
}
//抽象方法
public abstract void execute();
}
ConcreateCommand:
public class ConcreateCommand extends Command
{
public ConcreateCommand (Receiver receiver)
{
super(receiver);
}
public void execute()
{
receiver.request();
}
}
Invoker:
public class Invoker
{
private Command aommand;
public void setCommmand(Command command)
{
this.command=command;
}
public void execute()
{
command.execute();
}
}
Receiver:
public class Receiver
{
public void receiver()
{
System.out.println("this is receiver calss");
}
}
ReceiverTest:
public class ReceiverTest
{
public static void main(String []args)
{
Receiver receiver = new Receiver();
Commandcommand=newConcreateCommand(receiver);
Invoker invoker = new Invoker();
invoker.setCommand(command);
invoker.execute();
}
}
以上便是我最近学习软件设计模式的部分记录....
参考资料:疯狂java联盟总版主杨恩熊的《java设计模式》