java设计模式和应用场景.docx
《java设计模式和应用场景.docx》由会员分享,可在线阅读,更多相关《java设计模式和应用场景.docx(28页珍藏版)》请在冰豆网上搜索。
java设计模式和应用场景
Java常见设计模式应用场景
1、抽象工厂
应用场景:
封装变化点。
创建一系列相互依赖的对象。
在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时由于需求的变化,往往存在更多系列对象的创建工作。
如何应对这各变化如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合。
publicabstractClassAbstractFactory{
//创建一系列相互关联的对象如游戏场景中相互关联的Road,Building,Tunnel,Jungle对象
publicabstractProductAcreateProductA();
publicabstractProductBcreateProductB();
/........
}
//多系列体现在ConcreteFactoryA,ConcreteFactoryB这些具体工厂创建该系列下的多个相互关联的对象
publicclassConcreteFactoryAextendsAbstractFactory{
//具体创建ProductA,ProductB的哪个子类再这里指定,如
//这里相互关联的对象体现在ProductA1和ProductB1够成第一种风格
publicProductAcreateProductA(){
returnnewProductA1();
returnnewProductB1();
}
}
publicclassConcreteFactoryBextendsAbstractFactory{
//具体创建ProductA,ProductB的哪个子类再这里指定,如
publicProductAcreateProductA(){
returnnewProductA2();
returnnewProductB2();
}
}
publicabstractclassProductA{
//其子类是ProductA1,ProductA2
//定义一些接口;
publicvoidsomeMethod();
//......
}
publicabstarctclassProductB{
//其子类是ProductB1,ProductB2
//定义一些接口;
publicvoidsomeMethod();
//......
}
publicclassTest{
ProductAa;
ProductBb;
publicstaticvoidmain(String[]args){
//客户端要创建不同风格的游戏场景(多系列)
AbstractFactoryfactory=newConcreteFactoryA();
ProductAa=factory.createProductA();
ProductBb=factory.createProductB();
play();
//创建另一种风格的游戏场景,只须更改ConcreteFactoryB();
//
//AbstractFactoryfactory=newConcreteFactoryA();
//ProductAa=factory.createProductA();
//ProductBb=factory.createProductB();
//play();
}
publicstaticvoidplay(){
a.someMethod();
b.someMethod();
}
}
2、Builder
在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
Builder设计模式是应对这样的需求变化:
如何提供一种“封装机制”来隔离“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”,不随着需求改变而改变。
//抽象定义如何构建Product及其子对象
publicabstractclassBuilder{
//获取整体对象
publicabstractProductgetProduct();
//构建部分对象
publicabstractvoidbuildProductA();
publicabstractvoidbuildProductB();
publicabstractvoidbuildProductC();
}
//具体构建Product对象
publicclassConcreteBuilderextendsBuilder{
//复杂对象是由其他子对象组合而成,Houser是由ProductA,productB,productC的一个或者多个实例组合而成
privateProductproduct;
privateListproductAList=newArrayList();
privateListproductBList=newArrayList();
privateListproductCList=newArrayList();
//返回该复杂对象
publicProductgetProduct(){
product.setProductAList(this.productAList);
product.setProductBList(this.productBList);
product.setProductCList(this.productCList);
returnthis.product;
}
//构建ProductA
publicvoidbuildeProductA(){
this.productAList.add(newProductAA());
//this.productAList.add(newProductAB());
}
//构建ProductB
publicvoidbuildeProductB(){
this.productBList.add(newProductBA());
//this.productBList.add(newProductBB());
}
//构建ProductC
publicvoidbuildeProductC(){
this.productCList.add(newProductCA());
//this.productCList.add(newProductCB());
}
}
//复杂对象是由其他子对象组合而成,包含ProductA,ProductB,ProductC的实例
publicabstractclassProduct{
privateListProductAList;
privateListproductBList;
privateListproductCList;
//...........
}
publicclassTest{
//定义构建Product的稳定的算法,如构建1个ProductA,两个ProductB,三个ProductC
//这个复杂对象面临剧烈的变化是指ProductA有子类ProductAA,ProductAB;ProductB有
//子类ProductBA,ProductBB;ProductC有子类ProductCA,ProductCB,这些具体子类的构建
//封装在具体的ConcreteBuilder里,客户端只须修改ConcreteBuilder即可
publicstaticProductcreateProduct(Builderbuilder){
//如第一步创建1个ProductA
builder.createProductA();
//第二步两个ProductB
builder.createProductB();
builder.createProductB();
//第三步创建三个ProductC
builder.createProductC();
builder.createProductC();
builder.createProductC();
//最终才能获得Product对象
returnbuilder.getProduct();
}
publicstaticvoidmain(String[]args){
Builderbuilder=newConcreteBuilder();
Productproduct=this.createProduct(builder);
}
}
3、工厂方法(把变和不变的地方隔离出来)
紧耦合和松耦合:
如何进行模块划分?
主模块(抽象部分)-->次模块(细节具体部分)对模块进行分析(高层模块-->低层模块)
在软件系统中,经常面临着“某个对象”的创建工作;由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口。
如何应对这种变化?
如何提供一种“封装机制”来隔离出“这种易变对象”的变化,从而保持系统中
“其他依赖该对象的对象(主逻辑)”不随着需求改变而改变?
解决:
定义一个用于创建对象的接口,让子类决定实例化哪一个类。
FactoryMethod使得一个类的实例化延迟。
publicabstractClassCar{
//定义一系列稳定的接口
}
publicClassBMWextendsCar{
//overridecar'smethod
}
publicabstractClassAbstractFactory{
//只依赖于抽象Car,具体的Car延迟到具体的工厂中创建
publicCarcreateCar();
}
publicClassBMWFactory{
@override
publicCarcreateCar(){
returnnewBMW();
}
}
publicClassTest{
//客户端程序只依赖抽象的Car和抽象的AbstractFactory
//如果系统扩展其他车,只须修改这处的代码=newBMWFactory();(当然可以放到配置文件中读取出来就不用改代码了)
//另外加两个类publicClassKaiYueextendsCar,publicClassKaiYueFactoryextendsAbstractFactory
AbstractFactoryfactory=newBMWFactory();
Carcar=factory.createCar();
}
4、Bridge模式
适用场景:
将抽象部分与实现部分分离,使他们都可以独立地变化将
或将一个事物的多个维度的变化分离,该模式证明聚合比继承好
//最初的做法是将两个维度的抽象方法都集中在Abstraction中
//两个维度扩展出的所有子类都继承Abstraction,冗余太多
publicabstractionclassAbstraction{
publicabsractevoidoperate();
publicabsractevoidoperationImpl();
}
publicclassConcreteAbstractionAextendsAbstraction{
publicvoidoperate(){};
publicvoidoperationImpl(){};
}
publicclassConcreteAbstractionBextendsAbstraction{
publicvoidoperate(){};
publicvoidoperationImpl(){};
}
publicclassConcreteAbstractionConcreteImplementorA extendsConcreteAbstractionA{
publicvoidoperate(){};
public voidoperationImpl(){};
}
publicclassConcreteAbstractionConcreteImplementorB extendsConcreteAbstractionA{
publicabsractevoidoperate(){};
publicabsractevoidoperationImpl(){};
}
//............
//如果在多个维度上扩展,子类越来越多,实现代码有重复
改进后的代码
publicabstractclassAbstraction{
protectedImplemetorimplementor;
publlicAbstractor(Implementorimplementor){
this.implementor=implementor;
}
//定义一些其他抽象方法
publicabstractvoidoperation();
}
publicclassConcreteAbstractionextendsAbstraction{
publicConcreteAbstraction(Implementorimplementor){
super(implementor);
}
publicvoidoperation(){};
}
publicabstractImplementor{
publicabstractvoidoperationImpl();
}
publicclassConcreteImplementorAextendsImplementor{
}
publicclassConcreteImplementorBextendsImplementor{
}
publicclassTest{
publicstaticvoidmain(String[]args){
Implementorimplemetor=newConcreteImplementorA();
Abstractionabstraction=newConcreteAbstraction(implementor);
abstraction.operation();
implementor.operationImpl();
}
}
5、适配器Adapter
在软件系统中,由于应用环境的变化,常常要将"一些现在的对象"放到新的环境中应用,但是新环境要求的接口是这些现存对象所不满足的
适用场景:
在不改变原来实现的基础上,将原来不兼容的接口转换为兼容的接口。
将一个类的接口转换至客户希望的另一个接口。
Adapter
模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
//新环境所使用的接口,或者说是客户端想使用的接口
publicabstractTarget{
publicvoidrequest();
}
//已经存在的specificRequest接口
publicclassAdaptee{
publicvoidspecificRequest(){}
}
publicclassAdapterextendsTarget{
privateAdapteeadaptee;
publicAdapter(Adapteeadaptee){
this.adaptee=adaptee;
}
publicvoidrequest(){
//处理其它事项
//适配到目标接口
adaptee.specificRequest();
//处理其它事项
}
}
publicclassClient{
publicstaticvoidmain(String[]args){
Adapteradapter=newAdapter(newAdaptee());
adapter.request();
}
}
6、Decarator
过度地使用了继承来扩展对象的功能,由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性
并且随着子类的增多,各子类的组合会导致更多子类的膨胀.动态地给一个对象增加一些额外的职责
publicabstractclassComponent{
//定义一些抽象方法
publicabstractvoidoperation();
}
publicabstractclassConcreteComponent{
publicabstractvoid operation(){
//............原有功能
}
}
publicabstractclassDecorator{
privateComponentcomponent;
privateDecorator(Componentcomponent){
ponent=component;
}
//原有operation的功能
publicvoidoperation(){
ponent.operation();
}
}
//一个具体的Decorator就是扩展了Component类的operation();
//如果在Component类中添加一个行为则需要用Visitor模式,定义一个预留的待扩充的接口,很类似
publicConcreteDecoratorAextendsDecorator{
publicConcreteDecoratorA(Decoratordecorator){
super(decorator);
}
}
publicConcreteDecoratorBextendsDecorator{
publicConcreteDecoratorB(Decoratordecorator){
super(decorator);
}
publicvoidoperation(){
//扩展operation的功能
//Dosomeextension
otherMethod1();
operation();
}
}
publicclassTest{
publicstaticvoidmain(String[]args){
Componentcomponent=newConcreteComponent();
Decoratordecorator1=newConcreteDecoratorA();
Decoratordecorator2=newConcreteDecoratorB();
}
publicvoidoperation(){
//扩展operation的功能
otherMethod2();
operation();
}
}
7、Command命令模式
对发送者和接收者完全解耦
publicabstractclassSender{
privateCommandcommand;
publicSender(Commandcommand){
mand=command;
}
//发送命令
publicabstractsend(Commandcommand);
}
//命令调度者,发送什么样的命令以及通告谁执行命令
publicclassCommandInvoker{
privateCommandcommandA;
privateCommandcommandB;
privateComm