Java设计模式是在软件开发中广泛应用的一种经验总结,在一些大型软件系统中,设计模式可以有效提高代码的可维护性、可扩展性和可重用性,极大的提升软件开发效率。在本文中,我们将详细介绍23种Java设计模式,包括其定义、使用方法以及实例案例。
一、创建型模式
1.单例模式
单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点。单例模式主要有两种实现方式:懒汉式和饿汉式。懒汉式是在第一次调用时创建实例,而饿汉式则是在类装载时创建实例。
例如,我们定义了一个单例类:
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
在使用时,可以通过调用getInstance()方法获取该实例:
Singleton singleton = Singleton.getInstance();
2.工厂方法模式
工厂方法模式是一种创建型设计模式,其定义了一个创建对象的接口,但让子类来决定哪个类实例化。工厂方法模式是为了解决简单工厂模式的缺点而出现的,它使得类的实例化延迟到其子类。
例如,我们定义了一个抽象工厂类:
public abstract class Factory {
abstract Product createProduct();
}
其中,Product是一个抽象产品类,而createProduct()是一个抽象工厂方法,用于返回具体产品类的实例。
现在,我们定义了两个具体产品类:
public class ConcreteProduct1 extends Product {
public ConcreteProduct1() {
System.out.println("ConcreteProduct1 created");
}
}
public class ConcreteProduct2 extends Product {
public ConcreteProduct2() {
System.out.println("ConcreteProduct2 created");
}
}
然后,我们分别定义两个具体工厂类:
public class ConcreteFactory1 extends Factory {
@Override
public Product createProduct() {
return new ConcreteProduct1();
}
}
public class ConcreteFactory2 extends Factory {
@Override
public Product createProduct() {
return new ConcreteProduct2();
}
}
现在,我们可以通过具体工厂类来创建具体产品对象:
Factory factory1 = new ConcreteFactory1();
Product product1 = factory1.createProduct();
Factory factory2 = new ConcreteFactory2();
Product product2 = factory2.createProduct();
3.抽象工厂模式
抽象工厂模式是一种创建型设计模式,其定义了一个接口,用于创建相关或者依赖对象的家族,而不需要明确指定具体类。抽象工厂模式可以用于隐藏并封装直接创建对象的代码。
例如,我们定义了两个产品族:产品A和产品B,每个产品族都有两个产品:A1、A2和B1、B2。我们可以分别定义两个产品类:
public abstract class ProductA {
public abstract void show();
}
public abstract class ProductB {
public abstract void show();
}
再定义四个具体产品类:
public class ConcreteProductA1 extends ProductA {
@Override
public void show() {
System.out.println("ConcreteProductA1 show");
}
}
public class ConcreteProductA2 extends ProductA {
@Override
public void show() {
System.out.println("ConcreteProductA2 show");
}
}
public class ConcreteProductB1 extends ProductB {
@Override
public void show() {
System.out.println("ConcreteProductB1 show");
}
}
public class ConcreteProductB2 extends ProductB {
@Override
public void show() {
System.out.println("ConcreteProductB2 show");
}
}
然后定义一个抽象工厂类:
public abstract class Factory {
abstract ProductA createProductA();
abstract ProductB createProductB();
}
再定义两个具体工厂:
public class ConcreteFactory1 extends Factory {
@Override
public ProductA createProductA() {
return new ConcreteProductA1();
}
@Override
public ProductB createProductB() {
return new ConcreteProductB1();
}
}
public class ConcreteFactory2 extends Factory {
@Override
public ProductA createProductA() {
return new ConcreteProductA2();
}
@Override
public ProductB createProductB() {
return new ConcreteProductB2();
}
}
现在,我们可以使用具体工厂类来创建具体产品:
Factory factory1 = new ConcreteFactory1();
ProductA productA1 = factory1.createProductA();
ProductB productB1 = factory1.createProductB();
Factory factory2 = new ConcreteFactory2();
ProductA productA2 = factory2.createProductA();
ProductB productB2 = factory2.createProductB();
二、结构型模式
4.适配器模式
适配器模式是一种结构型设计模式,其意图是将一个类的接口转换成另一个客户端期望的接口。适配器模式可以使得原本不兼容的类一起工作。
例如,我们定义了一个老的接口:
public interface OldInterface {
void oldMethod();
}
现在我们要开发一个新功能,但是新功能的接口与老的接口不同,我们需要进行适配:
public interface NewInterface {
void newMethod();
}
我们可以创建一个适配器类,实现新的接口,并继承老的接口:
public class Adapter implements NewInterface, OldInterface {
private OldInterface oldInterface;
public Adapter(OldInterface oldInterface) {
this.oldInterface = oldInterface;
}
@Override
public void oldMethod() {
oldInterface.oldMethod();
}
@Override
public void newMethod() {
System.out.println("newMethod");
}
}
现在,我们可以通过适配器类来适配旧接口并实现新功能:
OldInterface oldInterface = new OldInterface() {
@Override
public void oldMethod() {
System.out.println("oldMethod");
}
};
NewInterface newInterface = new Adapter(oldInterface);
newInterface.newMethod();
5.桥接模式
桥接模式是一种结构型设计模式,其意图是将抽象部分与它的实现部分分离,以便两者都可以独立地变化。桥接模式使用组合的方式来实现抽象和实现的分离。
例如,我们定义了一个抽象部分:
public abstract class Abstraction {
protected Implementor implementor;
public Abstraction(Implementor implementor) {
this.implementor = implementor;
}
public abstract void operation();
}
其中,我们抽象出了一个operation()方法。
然后我们定义了一个实现部分:
public interface Implementor {
void operation();
}
现在我们定义两个具体实现类:
public class ConcreteImplementor1 implements Implementor {
@Override
public void operation() {
System.out.println("ConcreteImplementor1 operation");
}
}
public class ConcreteImplementor2 implements Implementor {
@Override
public void operation() {
System.out.println("ConcreteImplementor2 operation");
}
}
最后,我们使用组合将抽象部分和实现部分组合起来:
Abstraction abstraction1 = new RefinedAbstraction(new ConcreteImplementor1());
abstraction1.operation();
Abstraction abstraction2 = new RefinedAbstraction(new ConcreteImplementor2());
abstraction2.operation();
6.装饰器模式
装饰器模式是一种结构型设计模式,其意图是动态地给一个对象添加一些额外的职责。装饰器模式在不修改原有类的情况下,对对象进行功能增强。
例如,我们定义了一个抽象组件:
public interface Component {
void operation();
}
然后我们定义了一个具体组件类:
public class ConcreteComponent implements Component {
@Override
public void operation() {
System.out.println("ConcreteComponent operation");
}
}
现在我们定义了一个抽象装饰器:
public abstract class Decorator implements Component {
protected Component component;
public Decorator(Component component) {
this.component = component;
}
public void operation() {
component.operation();
}
}
现在我们可以定义一个具体装饰器类:
public class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
public void operation() {
super.operation();
addedBehavior();
}
public void addedBehavior() {
System.out.print("added Behavior");
}
}
最后,我们可以修改原有对象而不需要修改其接口:
Component component = new ConcreteComponent();
Component decorator = new ConcreteDecorator(component);
decorator.operation();
7.外观模式
外观模式是一种结构型设计模式,其意图是为一个复杂的系统提供一个简单的接口。外观模式通过对复杂系统进行简化,使客户端可以更容易地访问系统中的功能。
例如,我们定义了一个复杂的类:
public class ComplexClass {
private SubSystem1 sub1;
private SubSystem2 sub2;
private SubSystem3 sub3;
public ComplexClass() {
sub1 = new SubSystem1();
sub2 = new SubSystem2();
sub3 = new SubSystem3();
}
public void methodA() {
sub1.method1();
sub2.method2();
}
public void methodB() {
sub2.method2();
sub3.method3();
}
}
然后我们定义了三个子系统类:
public class SubSystem1 {
public void method1() {
System.out.println("SubSystem1 method1");
}
}
public class SubSystem2 {
public void method2() {
System.out.println("SubSystem2 method2");
}
}
public class SubSystem3 {
public void method3() {
System.out.println("SubSystem3 method3");
}
}
最后,我们定义了一个外观类来封装上述复杂类的功能:
public class Facade {
private ComplexClass complex;
public Facade() {
complex = new ComplexClass();
}
public void methodA() {
complex.methodA();
}
public void methodB() {
complex.methodB();
}
}
现在,我们可以通过外观类来使用复杂类的功能:
Facade facade = new Facade();
facade.methodA();
facade.methodB();
8.享元模式
享元模式是一种结构型设计模式,其意图是通过共享相同的对象来最小化内存使用。享元模式避免在每个对象实例中存储同样的数据,从而提高了系统的性能。
例如,我们定义了一个Flyweight接口:
public interface Flyweight {
void print();
}
然后我们可以实现该接口:
public class ConcreteFlyweight implements Flyweight {
private String string;
public ConcreteFlyweight(String string){
this.string = string;
}
public void print() {
System.out.print(string);
}
}
然后,我们定义了一个享元工厂类:
public class FlyweightFactory {
private Map public Flyweight getFlyweight(String key) { Flyweight flyweight = map.get(key); if (flyweight == null) { flyweight = new ConcreteFlyweight(key); map.put(key, flyweight); } return flyweight; } } 最后,我们可以使用享元工厂来获取具体的享元对象: FlyweightFactory factory = new FlyweightFactory(); Flyweight flyweight1 = factory.getFlyweight("Hello "); flyweight1.print(); Flyweight flyweight2 = factory.getFlyweight("World"); flyweight2.print(); 9.代理模式 代理模式是一种结构型设计模式,其意图是为委托类提供一种代理,以控制委托类的访问。代理模式允许我们通过代理类增加一些额外的功能,例如权限控制、日志记录等。 例如,我们定义了一个抽象Subject类: public interface Subject { void request(); } 然后我们定义了一个具体Subject类: public class ConcreteSubject implements Subject { @Override public void request() { System.out.println("ConcreteSubject request"); } } 现在我们定义了一个代理类,用于对访问Subject对象进行控制: public class Proxy implements Subject { private Subject subject; public Proxy(Subject subject) { this.subject = subject; } @Override public void request() { System.out.println("before request"); subject.request(); System.out.println("after request"); } } 最后,我们可以使用代理类来创建对象: Subject subject = new ConcreteSubject(); Subject proxy = new Proxy(subject); proxy.request(); 三、行为型模式 10.模板方法模式 模板方法模式是一种行为型设计模式,其意图是定义一个操作中的算法的骨架,而子类可以为一个或多个步骤提供实现。模板方法模式允许我们在修改算法结构的同时保持其他步骤不变。 例如,我们定义了一个抽象类: public abstract class AbstractClass { public void templateMethod() { operation1(); operation2(); } protected abstract void operation1(); protected abstract void operation2(); } 然后,我们定义了两个具体子类: public class ConcreteClass1 extends AbstractClass { protected void operation1() { System.out.println("ConcreteClass1 operation1"); } protected void operation2() { System.out.println("ConcreteClass1 operation2"); } } public class ConcreteClass2 extends AbstractClass { protected void operation1() { System.out.println("ConcreteClass2 operation1"); } protected void operation2() { System.out.println("ConcreteClass2 operation2"); } } 现在,我们使用模板方法来测试上述类: AbstractClass abstractClass1 = new ConcreteClass1(); abstractClass1.templateMethod(); AbstractClass abstractClass2 = new ConcreteClass2(); abstractClass2.templateMethod(); 11.命令模式 命令模式是一种行为型设计模式,其意图是将一个请求封装成一个对象,从而使我们可以用不同的请求对客户端进行参数化。命令模式允许我们异步、延迟、重复处理请求。 例如,我们定义了一个接口: public interface Command { void execute(); } 然后,我们定义了一个具体类: public class ConcreteCommand implements Command { private Receiver receiver; public ConcreteCommand(Receiver receiver) { this.receiver = receiver; } public void execute() { receiver.action(); } } 接着,我们定义了一个Receiver类: public class Receiver { public void action() { System.out.println("Receiver action"); } } 最后我们定义了一个Invoker类: public class Invoker { private Command command; public void setCommand(Command command) { this.command = command; } public void executeCommand() { command.execute(); } } 现在,我们可以通过Invoker对象来启动具体命令: Receiver receiver = new Receiver(); Command command = new ConcreteCommand(receiver); Invoker invoker = new Invoker(); invoker.setCommand(command); invoker.executeCommand(); 12.迭代器模式 迭代器模式是一种行为型设计模式,其意图是为容器对象提供一种访问其元素的方式。迭代器提供了一种方法来顺序访问聚合对象的元素,而无需披露其内部结构。 例如,我们定义了一个抽象迭代器接口: public interface Iterator { boolean hasNext(); Object next(); } 然后,我们定义了一个具体聚合类: public class ConcreteAggregate implements Aggregate { private List
发表评论 取消回复