Java常见设计模式应用场景

本文深入讲解了11种常用的设计模式,包括抽象工厂、建造者、工厂方法等,旨在帮助开发者掌握灵活应对需求变化的设计技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、抽象工厂
应用场景:封装变化点。创建一系列相互依赖的对象。
在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时由于需求的变化,往往存在更多系列对象的创建工作。如何应对这各变化如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合。
public abstract Class AbstractFactory{
    //创建一系列相互关联的对象如游戏场景中相互关联的Road,Building,Tunnel,Jungle对象
    public abstract ProductA createProductA();
    public abstract ProductB createProductB();
    /........
}
 
//多系列体现在ConcreteFactoryA,ConcreteFactoryB这些具体工厂创建该系列下的多个相互关联的对象 
public class ConcreteFactoryA extends AbstractFactory{
     //具体创建ProductA,ProductB的哪个子类再这里指定,如
    //这里相互关联的对象体现在ProductA1和ProductB1够成第一种风格
    public ProductA createProductA(){
        return new ProductA1();
        return new ProductB1();
    }
}
 
public class ConcreteFactoryB extends AbstractFactory{
    //具体创建ProductA,ProductB的哪个子类再这里指定,如
    public ProductA createProductA(){
        return new ProductA2();
        return new ProductB2();
    }
}
 
public abstract class ProductA{
    //其子类是ProductA1,ProductA2
    //定义一些接口;
    public void someMethod();
    //......
}
 
public abstarct class ProductB{
    //其子类是ProductB1,ProductB2
    //定义一些接口;
    public void someMethod();
    //......
}
 
public class Test{
    ProductA a;
    ProductB b;
    public static void main(String[] args){
        //客户端要创建不同风格的游戏场景(多系列)
        AbstractFactory factory = new ConcreteFactoryA();  
        ProductA a = factory.createProductA();
        ProductB b = factory.createProductB();
        play();
        
        //创建另一种风格的游戏场景,只须更改ConcreteFactoryB();
        //
        //AbstractFactory factory = new ConcreteFactoryA();  
        //ProductA a = factory.createProductA();
        //ProductB b = factory.createProductB();
        //play();
        
    }
 
    public static void play(){
        a.someMethod();
        b.someMethod();
    }
}



2、Builder
在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
Builder设计模式是应对这样的需求变化:如何提供一种“封装机制”来隔离“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”,不随着需求改变而改变。
 
//抽象定义如何构建Product及其子对象
public abstract class Builder{
    //获取整体对象
    public abstract Product getProduct();
    //构建部分对象
    public abstract void buildProductA();
    public abstract void buildProductB();
    public abstract void buildProductC();
}
 
//具体构建Product对象
public class ConcreteBuilder extends Builder{
    //复杂对象是由其他子对象组合而成,Houser是由ProductA,productB,productC的一个或者多个实例组合而成
    private Product product;
    private List<ProductA> productAList = new ArrayList();
    private List<ProductB> productBList = new ArrayList();
    private List<ProductC> productCList = new ArrayList();
    //返回该复杂对象
    public Product getProduct(){
        product.setProductAList(this.productAList);
        product.setProductBList(this.productBList);
        product.setProductCList(this.productCList);
        return this.product;
    }
    //构建ProductA
    public void buildeProductA(){
        this.productAList.add(new ProductAA());
        //this.productAList.add(new ProductAB());
    }
    //构建ProductB
    public void buildeProductB(){
        this.productBList.add(new ProductBA());
        //this.productBList.add(new ProductBB());
    }
    //构建ProductC
    public void buildeProductC(){
        this.productCList.add(new ProductCA());
        //this.productCList.add(new ProductCB());    
    }
     
}
 
//复杂对象是由其他子对象组合而成,包含ProductA,ProductB,ProductC的实例
public abstract class Product{
    private List ProductAList;
    private List productBList;
    private List productCList;
    //...........    
}
 
public class Test{
    //定义构建Product的稳定的算法,如构建1个ProductA,两个ProductB,三个ProductC
    //这个复杂对象面临剧烈的变化是指ProductA有子类ProductAA,ProductAB;ProductB有
    //子类ProductBA,ProductBB;ProductC有子类ProductCA,ProductCB,这些具体子类的构建
    //封装在具体的ConcreteBuilder里,客户端只须修改ConcreteBuilder即可
 
    public static Product createProduct(Builder builder){
        //如第一步创建1个ProductA
        builder.createProductA();
        
        //第二步两个ProductB
        builder.createProductB();
        builder.createProductB();
 
        //第三步创建三个ProductC
        builder.createProductC();
        builder.createProductC();
        builder.createProductC();
 
        //最终才能获得Product对象
        return builder.getProduct();
    }  
 
    public static void main(String[] args){
        Builder builder = new ConcreteBuilder();
        Product product = this.createProduct(builder);
    }
}


3、工厂方法(把变和不变的地方隔离出来)
紧耦合和松耦合:如何进行模块划分?
主模块(抽象部分)-->次模块(细节具体部分) 对模块进行分析(高层模块-->低层模块)
在软件系统中,经常面临着“某个对象”的创建工作;由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口。
如何应对这种变化?如何提供一种“封装机制”来隔离出“这种易变对象”的变化,从而保持系统中
“其他依赖该对象的对象(主逻辑)”不随着需求改变而改变?
解决:定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟。
public abstract Class Car{
    //定义一系列稳定的接口
}
 
public Class BMW extends Car{
    //override car's method
}
 
public abstract Class AbstractFactory{
    //只依赖于抽象Car,具体的Car延迟到具体的工厂中创建
    public Car createCar();
}
public Class BMWFactory{
    @override
    public Car createCar(){
        return new BMW();
    }
}
 
public Class Test{
    //客户端程序只依赖抽象的Car和抽象的AbstractFactory
    //如果系统扩展其他车,只须修改这处的代码 = new BMWFactory();(当然可以放到配置文件中读取出来就不用改代码了)
    //另外加两个类public Class KaiYue extends Car,public Class KaiYueFactory extends AbstractFactory
    AbstractFactory factory = new BMWFactory();
    Car car = factory.createCar();
}
 

 
4、Bridge模式
适用场景:将抽象部分与实现部分分离,使他们都可以独立地变化将
            或将一个事物的多个维度的变化分离,该模式证明聚合比继承好
 
//最初的做法是将两个维度的抽象方法都集中在Abstraction中
//两个维度扩展出的所有子类都继承Abstraction,冗余太多
public abstraction class Abstraction{
    public absracte void operate();
    public absracte void operationImpl();
}
 
public class ConcreteAbstractionA extends Abstraction{
    public void operate(){ };
    public void operationImpl(){ };
}
 
public class ConcreteAbstractionB extends Abstraction{
    public void operate(){ };
    public void operationImpl(){ };
}
 
public class ConcreteAbstractionConcreteImplementorA  extends ConcreteAbstractionA{
    public void operate(){ };
    public  void operationImpl(){ };
 
public class ConcreteAbstractionConcreteImplementorB  extends ConcreteAbstractionA{
     public absracte void operate(){ };
     public absracte void operationImpl(){ };
}
//............
//如果在多个维度上扩展,子类越来越多,实现代码有重复
 
 
改进后的代码
public abstract class Abstraction{
    protected Implemetor implementor;
    publlic Abstractor(Implementor implementor){
        this.implementor = implementor;
    }
    //定义一些其他抽象方法
    public abstract void operation();     
 
}
 
public class ConcreteAbstraction extends Abstraction{
    public ConcreteAbstraction(Implementor implementor){
        super(implementor);
    }
    public void operation(){ };
}
 
public abstract Implementor{
    public abstract void operationImpl();
}
 
public class ConcreteImplementorA extends Implementor{
    
}
 
public class ConcreteImplementorB extends Implementor{
    
}
 
 
public class Test{
   public static void main(String[] args){
        Implementor implemetor = new ConcreteImplementorA();
        Abstraction abstraction = new ConcreteAbstraction(implementor);
        abstraction.operation();
        implementor.operationImpl();
    }
}
 
 
5、适配器Adapter
在软件系统中,由于应用 环境的变化,常常要将"一些现在的对象"放到新的环境中应用,但是新环境要求的接口是这些现存对象所不满足的
适用场景:在不改变原来实现的基础上,将原来不兼容的接口转换为兼容的接口。将一个类的接口转换至客户希望的另一个接口。Adapter
           模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
//新环境所使用的接口,或者说是客户端想使用的接口
public abstract Target{
    public void request();
}
 
//已经存在的specificRequest接口
public class Adaptee{
    public void specificRequest(){ }
}
 
public class Adapter extends Target{
    private Adaptee adaptee;
    public Adapter(Adaptee adaptee){
        this.adaptee = adaptee;
    }
    public void request(){
         //处理其它事项
        //适配到目标接口
        adaptee.specificRequest();
        //处理其它事项
    }
    
}
 
public class Client{
    public static void main(String[] args){
        Adapter adapter = new Adapter(new Adaptee());
        adapter.request();
    }
}
 
 
6、Decarator
过度地使用了继承来扩展对象的功能,由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性
并且随着子类的增多,各子类的组合会导致更多子类的膨胀.动态地给一个对象增加一些额外的职责
public abstract class Component{
    //定义一些抽象方法
    public abstract void operation();
}
 
public abstract class ConcreteComponent{
    public abstract void  operation(){
        //............原有功能
    }
}
 
public abstract class Decorator{
    private Component component;
    private Decorator(Component component){
        this.component = component;
    }
    //原有operation的功能
    public void operation(){
        this.component.operation();
    }
}
 
//一个具体的Decorator就是扩展了Component类的operation();
//如果在Component类中添加一个行为则需要用Visitor模式,定义一个预留的待扩充的接口,很类似 
public ConcreteDecoratorA extends Decorator{
    public ConcreteDecoratorA(Decorator decorator){
        super(decorator);
    }
}
 
public ConcreteDecoratorB extends Decorator{
    public ConcreteDecoratorB(Decorator decorator){
        super(decorator);
    }
    public void operation(){
        //扩展operation的功能
        // Do some extension
        otherMethod1();
        operation();
    }
}
 
public class Test{
    public static void main(String[] args){
        Component component = new ConcreteComponent();
        Decorator decorator1 = new ConcreteDecoratorA();
        Decorator decorator2 = new ConcreteDecoratorB();
    }
    public void operation(){
        //扩展operation的功能
        otherMethod2();
        operation();
    }
}
 
7、Command命令模式
对发送者和接收者完全解耦
public abstract class Sender{
    private Command command;
    public Sender(Command command){
        this.command = command;        
    }
    //发送命令
    public abstract send(Command command);
    
}
 
//命令调度者,发送什么样的命令以及通告谁执行命令
public class CommandInvoker{
    private Command commandA;
    private Command commandB;
    private Command commandC;
    public CommandInvoker(Command commandA,Command commandB,Command commandC){
        this.commandA = commandA;
        this.commandB = commandB;
        this.commandC = commandC;
    }
    //这里已经确定命令是发给谁执行的,以及系统中只有三个命令CommandA,CommandB,CommandC
    //如果再加一个CommandD命令,command命令模式已无能为力,这里应该采用Visitor模式,如何将两者结合起来
    public void executeCommandA(){
        commandA.execute();
    }
    
    public void executeCommandB(){
        commandB.execute();
    }
}
public Interface Command{
    public void execute();
}
 
public class CommandA implements Command{
    private Receiver receiver;
    public CommandA(Receiver receiver){
        this.receiver = receiver;
    }
    public void execute(){
        //真正的命令执行者是Receiver
        receiver.execute();
    }
}
 
public class CommandB implements Command{
    private Receiver receiver;
    public CommandB(Receiver receiver){
        this.receiver = receiver;
    }
    public void execute(){
        //真正的命令执行者是Receiver
        receiver.execute();
    }
}
 
//命令接收者
public class Receiver{
    public void executeCommandA(){
        //.......
    }
    public void executeCommandB(){
        //.......
    }
}
public class Test{
    public static void main(String[] args){
        //客户端只须定义一个命令,交给手下CommandInvoker去执行就行了
        //至于具体的命令通知谁做什么事以及怎么执行不关注
        CommandA commandA = new CommandA();
        CommandB commandB = new CommandB();
        CommandC commandC = new CommandC();
        CommandInvoker invoker = new CommandInvoker(commandA,commandB,commandC);            
        commandA.execute();
        commandB.execute();
        commandC.exceute();
        //问题,为什么非要执行三个命令呢?只执行一个命令我也要new CommandA,CommandB,CommandC
        
        //最初的Comand是这样的
        /**
            public class Command{
                public void  executeCommandA(){}; 
                public void  executeCommandB(){};    
            }
            //客户端程序,请求者和耦合度高,command模式将一个请求封装为一个对象:将每一个executeCommandA()封装成CommandA
            //从而使你可用不同的请求对客户(行为的请求者)进行参数化:CommandInvoker invoker = new CommandInvoker(commandA,commandB,commandC);   
            Command comand = new Command();
            command.executeCommandA();
            command.executeCommandB();
            
        */
            
    }
}
 


8、Visitor模式
场景是:在类层次结构稳定,而操作却面临频繁的变动
解决的问题是:在类层次结构的父类中要添加新的行为,这里所有的子类不得不跟着改动
解决方法是:只须添加一个Visitor就可以将所有子类的必须实现的方法集中到Visitor类中

public interface P{
    //系统已有的方法
    public void someMethod();
 
    //预留的防止系统需要添加的新行为
    public void accept(Visitor visitor);
}

public class PA implements P{
    public void someMethod{
    
    }

    public void accep(Visitor visitor){
        //把自己传进来PA类型
        //这里使用了double dispatch 1:visitor的多态;2:this的转换(但是在静态编译过程中已经确定了)
        visitor.run(this);
    }
}

public class PB implements P{
     //把自己传进来PB类型
     visitor.run(this);
}

public class PC implements P{
     //把自己传进来PC类型
     visitor.run(this);
}

public abstract class Visitor{
    //对应于三个子类要重写的子类方法
    public abstract void run(PA pa);
    public abstract void run(PB pb);
    publilc abstract void run(PC pc);
}
 
public class MyVisitor extends Visitor{
    public abstract void run(PA pa){
        //具体PA子类的实现,复写的逻辑代码
        //..........
    }
 
    public abstract void run(PB pb){
        //具体PB子类的实现,复写的逻辑代码
        //..........    
    }
 
    publilc abstract void run(PC pc);{
        //具体PC子类的实现,复写的逻辑代码
        //..........
    }
}

//ArrayList list = new ArrayList();
list.add(new PA());
list.add(new PB());
list.add(new PC());

Visitor vistor = new Visitor();
Iterator it = new Iterator();
while(it.hasNext()){
    P p = (P) it.next();
    p.accept(visitor);
}

9、Strategy模式
某些对象使用的算法可能多种多样经常改变
策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。
public class Calculator{
    public String calculate(float a,float b,String type){
         //变化点1 type; 2processA();
        if(type.equals "A"){
            processA();
        }else if(type.equals "B"){
            processB();
        }else if(type.equals "C"){
            processC();
        }
        else if(type.equals "D"){
            processD();
        }

        return new Point();
    } 
 
    protected void processA(){  
    }
 
    protected void processB(){  
    }
 
    protected void processC(){  
    }
 
    protected void processD(){  
    }
}
//采用设计模式后的代码
public abstract class Strategy{
    public abstract String calculate(float a,float b);
}
 
public class StrategyA extends Strategy{
    public String calculate(float a,float b){
        //......
    }
}
 
public class StrategyB extends Strategy{
    public String calculate(float a,float b){
        //......
    }
}
 
public class StrategyC extends Strategy{
    public String calculate(float a,float b){
        //......
    }
}
 
public class StrategyD extends Strategy{
    public String calculate(float a,float b){
        //......
    }
}
 
public class Context{
    private Strategy strategy;
    public Context(Strategy strategy){
        this.strategy = strategy;
    }
    public String calculate(float a,float b){
        //调用具体的子策略的execute();
       return strategy.execute(a,b);
    }
}
 
public class Test{
    public static void main(String[] args){
        float a = 200;
        float b = 50;
 
        Context context = new Context(new StrategyA());
        context.execute(a,b);
 
        Context context = new Context(new StrategyB());
        context.execute(a,b);
 
        Context context = new Context(new StrategyC());
        context.execute(a,b);
 
        Context context = new Context(new StrategyD());
        context.execute(a,b);
    }
}

10、代理
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
 
//抽象角色:声明真实对象和代理对象的共同接口;
public abstract class Subject{
    public abstract void request();
}
 
public class RealSubject extends Subject{
    public void request{
        
    }
}
//代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装
public class ProxySubject extends Subject{
    //真实主题
    private   RealSubject realSubject; 
    public ProxySubject(){
        
    }
    public void request{
        //......附加操作    
        if(null != realSubject){
            realSubject = new RealSubject();
            realSubject.request();
        }
         //....附加操作
    }
}
 
java的动态代理
public interface Subject{
    public void request();
 
public class RealSubject implements Subject{
    public void request{
        //.......
    }
}
 
//动态代理角色
public class DynamicProxySubject implements InvocationHandler{
    private Object subject;
    public DynamicProxSubject(){
    
    }
    //被代理的对象
    public DynamicProxySubject(Object obj){
        this.subject = obj;
    }
    
    public Object invoke(Object proxy,Method method,Object[] args)throws Throwable{
        //之前加上一些处理
        return method.invoke(subject,args);
        //之后加上一些处理
    }
    
    //传入被代理对象,返回代理商对象
    public Object bind(Object subject){
        reuturn Proxy.newProxyInstance(subject.getClass().getClassLoader(),subject.getClass().getInterfaces(),this);
    }
}
 
public class Test{
    public static void main(String[] arg){
            //被代理对象,也是真实主题
            RealSubject  realSubject = new RealSubject();
            DynamicProxySubject  dynamicProxy =  new DynamicProxySubject(realSubject);
            Subject proxy = (Subject)dynamicProxy.bind(realSubject);
            proxy.request();
    }
}
 
//动态代理在日志模块中的运用
public interface BusinessInterface{
    public void proceeBusiness();
}
 
public class BusinessObject implements BusinessInterface{
    /**
    *private Logger logger = Logger.getLogger(this.getClass().getName());
    *public void processBusiness(){
    *   logger.info("begin process...");
    *   //....... this is business logic
    *   logger.info("after process...");
    *}
    */
    //运用代理之后,日志移至代理类中
    public void processBusiness(){
        //......this is business logic here;
        Sysem.out.println("business logic......");
    }
}
 
public class LoggerProxy implements InvocationHandler{
    private Logger logger = Logger.getLogger(this.getClass().getName());
    //被代理对象
    private Object origin;//.....这里是BusinessObject的实现
    public LoggerProxy(Object origin){
        this.origin = origin;
    }
    
    public Object invoke(Object proxy,Method method,Ojbect[] args){
        //所有对日志的处理移至这里
        Object obj = null;
        logger.info("method before..." + method);
        obj = origin.invoke(origin,method,args);        
        logger.info("method after..." + method);
        //返回方法的返回值
        return obj;
    }
    
    //返回代理对象,this指代LoggerProxy,origin是BusinessInterface的实现
    public Object bind(Object origin){
        return Proxy.newProxyInstance(origin.getClass().getClassLoader(),origin.getClass.getInterfaces(),this);
    }
}
 
public class Test{
    public static void main(String[] args){
        BusinessInterface businessObj = new BusinessObject();
        LoggerProxy dynamicProxy = new LoggerProxy(businessObj );
        BusinessInterface  proxyObj = (BusinessInterface)dynamicProxy.bind(businessObj);
        proxyObj.processBusiness();
        //print result
        //method before........
        //business logic......
        //method after.......
    }
}
 
 
11、责任链模式
//抽象类中包含一个具体子类对象的引用
public abstract class Handler{
    //下一个处理者
    protected Handler successor;
    //处理请求
    public void handleRequest(Request request){
        //如果下家处理者存在
        if(successor!=null){
            successor.next();
        }
    }
    
    public Handler getSuccessor(){
        return successor;
    }
    
    public void setSuccessor(Handler successor){
        this.successor = success
    }
}
 
//具体处理者持有下家处理者的引用
public class ConcreteHandlerA{
        
    public ConcreteHandlerA(Handler successor){
        this.setSuccessor(successor);
    }
 
    public absract void handleRequest(Request request){
        if(request.type=="1"){
            //....处理请求
        }else{
             //交给下家管理者
            getSuccessor().handleRequest(request);        
        } 
    }
}
 
//具体处理者持有下家处理者的引用
public class ConcreteHandlerB{
        
    public ConcreteHandlerB(Handler successor){
        this.setSuccessor(successor);
    }
 
    public absract void handleRequest(Request request){
        if(request.type=="2"){
            //处理请求
        }else{
             //如果下家处理者存在,交给下家管理者
            getSuccessor().handleRequest(request);
        } 
    }
}
 
 
//具体处理者持有下家处理者的引用
public class ConcreteHandlerC{
        
    public ConcreteHandlerC(Handler successor){
        this.setSuccessor(successor);
    }
 
    public absract void handleRequest(Request request){
        if(request.type=="3"){
            //处理请求
        }else{
             //如果下家处理者存在,交给下家管理者
            getSuccessor().handleRequest(request);
        } 
    }
}
 
public class Request{
    
}
 
public class Client{
    private static Handler handler1,handler2;
    public static void main(String args){
        handler1 = new ConcreteHandlerA(null);
        handler2 = new ConcreteHandlerB(handler1);
        handler3 = new ConcreteHandlerC(handler2);    
        handler1.handleRequest(new Request());
    }
}
<think>好的,我现在需要回答用户关于Java常见设计模式及其应用场景的问题。首先,我需要回顾一下设计模式的基本概念,然后整理出Java中常用的几种设计模式,并分别说明它们的定义、结构适用场景。 用户之前已经询问过MyBatis的动态SQL标签,现在转向设计模式,可能是在学习Java的高级主题,或者准备面试。因此,回答需要结构清晰,内容准确,同时结合实际应用场景,帮助用户理解何时使用这些模式。 首先,设计模式通常分为创建型、结构型行为型三类。我需要从每个类别中挑选几个最常用的模式。创建型可能包括单例、工厂、建造者;结构型如适配器、代理、装饰器;行为型如观察者、策略、责任链等。 接下来,每个模式的介绍需要包括:定义、核心角色(如果有)、典型应用场景,以及可能的Java SDK或框架中的例子。例如,单例模式用于全局唯一实例,工厂模式解耦对象的创建,适配器模式解决接口不兼容问题等。 需要注意避免过于技术化的描述,保持简洁易懂。同时,要确保每个模式的应用场景具体,让用户能够联想到实际开发中的情况。例如,Spring框架中的Bean默认是单例,Java中的Collections.sort()使用策略模式等。 另外,用户可能对某些模式的实现细节感兴趣,比如单例模式的双重检查锁定,工厂方法模式与抽象工厂的区别,但根据问题,重点应放在应用场景而非具体代码实现。不过,适当给出简单的代码示例有助于理解。 需要检查是否有遗漏的重要模式,比如代理模式在Spring AOP中的应用,或者观察者模式在事件驱动系统中的作用。确保覆盖常见的模式,但不需要列举所有23种,而是选择最常用的大约10个左右。 最后,总结部分可以强调设计模式解决特定问题的优点,以及过度使用可能带来的复杂性。提醒用户根据实际需求选择合适的模式,而不是为了使用模式而模式。 现在组织内容,分点介绍每个模式,保持段落简短,结构清晰,使用标题子标题帮助阅读。可能使用数字列表,每个模式一个条目,包含定义、结构、应用场景例子。 需要确保术语准确,比如“抽象工厂”与“工厂方法”的区别,避免混淆。同时,检查是否有拼写错误或概念错误,比如单例模式的线程安全问题,不同实现方式的优缺点。 可能还需要考虑用户的后续问题,比如如何选择合适的设计模式,或者某些模式之间的对比,但在当前回答中先专注于介绍常见的模式应用场景。 完成草稿后,通读一遍,确保逻辑连贯,例子恰当,语言通俗易懂,符合中文表达习惯,没有使用Markdown格式,符合用户要求的格式。</think>以下是 Java常见设计模式及其应用场景的清晰总结,帮助开发者理解何时使用这些模式解决实际问题: --- ### 一、创建型模式(关注对象创建) 1. **单例模式 (Singleton)** **定义**:确保一个类只有一个实例,并提供全局访问点。 **应用场景**: - 需要全局唯一资源时,如数据库连接池、日志管理器。 - 工具类避免重复创建对象。 **Java 示例**: ```java public class Singleton { private static volatile Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } } ``` 2. **工厂方法模式 (Factory Method)** **定义**:定义一个创建对象的接口,由子类决定实例化哪个类。 **应用场景**: - 需要解耦对象创建逻辑(如数据库驱动切换)。 - Spring 的 `BeanFactory` 通过配置生成对象。 **示例**: ```java public interface Car { void drive(); } public class Tesla implements Car { /* ... */ } public class CarFactory { public Car createCar(String type) { if ("tesla".equals(type)) return new Tesla(); else throw new IllegalArgumentException(); } } ``` 3. **抽象工厂模式 (Abstract Factory)** **定义**:提供一个接口,用于创建相关或依赖对象的家族,而无需指定具体类。 **应用场景**: - 需要创建一组关联对象(如跨平台 UI 组件:按钮 + 文本框)。 **Java 示例**: Java 的 `javax.xml.parsers.DocumentBuilderFactory` 根据配置生成 XML 解析器。 4. **建造者模式 (Builder)** **定义**:分步骤构建复杂对象,允许灵活配置。 **应用场景**: - 构造参数多且可选(如 `StringBuilder`、Lombok 的 `@Builder`)。 - 链式调用提升可读性。 **示例**: ```java User user = new UserBuilder().name("Alice").age(30).build(); ``` --- ### 二、结构型模式(关注对象组合) 5. **适配器模式 (Adapter)** **定义**:将一个类的接口转换为另一个接口,使不兼容的类可以协作。 **应用场景**: - 旧系统接口改造(如 JDBC 驱动适配不同数据库)。 **Java 示例**: `Arrays.asList()` 将数组适配为 `List` 接口。 6. **代理模式 (Proxy)** **定义**:为其他对象提供一种代理以控制对这个对象的访问。 **应用场景**: - 延迟加载(MyBatis 的 Mapper 代理)。 - AOP 实现日志、权限控制(Spring 动态代理)。 **示例**: ```java public interface Image { void display(); } public class ProxyImage implements Image { private RealImage realImage; public void display() { if (realImage == null) realImage = new RealImage(); realImage.display(); // 延迟加载实际图片 } } ``` 7. **装饰器模式 (Decorator)** **定义**:动态地为对象添加额外职责,比继承更灵活。 **应用场景**: - Java IO 流(如 `BufferedReader` 包装 `FileReader`)。 **示例**: ```java InputStream is = new BufferedInputStream(new FileInputStream("test.txt")); ``` --- ### 三、行为型模式(关注对象交互) 8. **观察者模式 (Observer)** **定义**:定义对象间的一对多依赖,当一个对象状态改变时,所有依赖者自动收到通知。 **应用场景**: - 事件驱动系统(如 GUI 按钮点击事件)。 **Java 示例**: Java 内置的 `java.util.Observable` `Observer` 接口(已过时,但概念广泛用于消息队列)。 9. **策略模式 (Strategy)** **定义**:定义一系列算法,使其可以相互替换,且算法的变化独立于客户端。 **应用场景**: - 支付方式切换(支付宝、微信支付)。 - `Collections.sort()` 通过 `Comparator` 指定排序策略。 **示例**: ```java public interface PaymentStrategy { void pay(int amount); } public class Alipay implements PaymentStrategy { /* ... */ } public class PaymentContext { private PaymentStrategy strategy; public void executePayment(int amount) { strategy.pay(amount); } } ``` 10. **责任链模式 (Chain of Responsibility)** **定义**:将请求的发送者接收者解耦,使多个对象都有机会处理请求。 **应用场景**: - 审批流程(如报销审批:经理→总监→CEO)。 - Servlet 过滤器链(`FilterChain`)。 --- ### 四、其他常用模式 11. **模板方法模式 (Template Method)** **定义**:定义一个算法骨架,将某些步骤延迟到子类实现。 **应用场景**: - 框架中固定流程(如 Spring 的 `JdbcTemplate` 执行 SQL 步骤固定,但 SQL 可变)。 12. **门面模式 (Facade)** **定义**:为复杂子系统提供一个统一的高层接口。 **应用场景**: - 简化 API 调用(如 SLF4J 封装不同日志框架)。 --- ### **总结:何时使用设计模式?** - **代码复用**:通过模式避免重复代码(如工厂解耦对象创建)。 - **扩展性**:预留扩展点(如策略模式支持新增算法)。 - **可维护性**:通过松耦合提升代码可读性(如观察者模式分离事件源监听者)。 - **避免过度设计**:优先遵循 KISS(Keep It Simple)原则,在复杂度上升时再引入模式。 合理使用设计模式能提升代码质量,但需结合具体场景,避免为模式而模式!
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值