1.设计模式的概念和作用
设计模式是解决软件设计中常见问题的通用解决方案。它们是针对一类问题的经验总结,是从过去的成功经验中总结出来的。设计模式可以让软件开发人员避免一些常见的错误,同时提高软件设计的复用性、可维护性、可扩展性和可读性。
设计模式可以分为三种类型:创建型模式、结构型模式和行为型模式。创建型模式包括单例模式、工厂模式、抽象工厂模式、建造者模式和原型模式。结构型模式包括适配器模式、桥接模式、装饰器模式、外观模式、享元模式和代理模式。行为型模式包括模板方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式和状态模式。
不同的设计模式适用于不同的场景。例如,单例模式适用于需要确保一个类只有一个实例的情况,工厂模式适用于需要创建一系列相关对象的情况,代理模式适用于需要控制对一个对象的访问的情况。设计模式不是一成不变的,而是随着问题的不同而有所变化。因此,软件开发人员需要根据实际情况选择合适的设计模式。
2.创建型设计模式的概述和分类
创建型设计模式是用于对象的创建和实例化的模式,旨在解决对象的创建问题,以便更加灵活地创建对象并将对象与使用它们的代码分离。创建型模式可以分为以下五种:
- 单例模式(Singleton Pattern):确保一个类只有一个实例,并提供对该实例的全局访问点。
- 工厂模式(Factory Pattern):定义一个用于创建对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类中。
- 抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或依赖对象的接口,而无需指定它们具体的类。
- 建造者模式(Builder Pattern):将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
- 原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并通过复制这些原型创建新的对象。
这些设计模式在实际应用中广泛使用,能够提高代码的复用性、可维护性和可扩展性。同时,它们也有不同的适用场景和优缺点,需要开发人员在实际应用中进行评估和选择。
3.简单工厂模式:工厂方法模式和抽象工厂模式
简单工厂模式、工厂方法模式和抽象工厂模式都是创建型设计模式,它们的目的都是将对象的创建与使用代码分离,提高代码的可扩展性和可维护性。
简单工厂模式(Simple Factory Pattern):又称为静态工厂方法模式,它通过一个工厂类来创建对象,而无需直接通过new关键字来实例化对象。这个工厂类根据传入的参数来确定要创建的对象类型。简单工厂模式只有一个工厂类,因此扩展性不如其他两种模式。但它实现起来简单,使用起来也比较方便。
// 创建产品接口
interface Product {
void show();
}
// 创建具体产品类
class ConcreteProduct1 implements Product {
@Override
public void show() {
System.out.println("具体产品1");
}
}
class ConcreteProduct2 implements Product {
@Override
public void show() {
System.out.println("具体产品2");
}
}
// 创建工厂类
class SimpleFactory {
public static Product createProduct(int type) {
switch (type) {
case 1:
return new ConcreteProduct1();
case 2:
return new ConcreteProduct2();
default:
return null;
}
}
}
// 测试类
public class SimpleFactoryDemo {
public static void main(String[] args) {
Product product1 = SimpleFactory.createProduct(1);
product1.show();
Product product2 = SimpleFactory.createProduct(2);
product2.show();
}
}
工厂方法模式(Factory Method Pattern):又称为多态性工厂模式,它定义一个用于创建对象的接口,但让子类决定实例化哪个类。这个工厂方法使一个类的实例化延迟到其子类中。这样做的好处是当需要添加新的产品时,只需要添加一个具体的产品类和一个对应的工厂类,而不需要修改现有的代码,符合开放封闭原则。
// 创建产品接口
interface Product {
void show();
}
// 创建具体产品类
class ConcreteProduct1 implements Product {
@Override
public void show() {
System.out.println("具体产品1");
}
}
class ConcreteProduct2 implements Product {
@Override
public void show() {
System.out.println("具体产品2");
}
}
// 创建工厂接口
interface Factory {
Product createProduct();
}
// 创建具体工厂类
class ConcreteFactory1 implements Factory {
@Override
public Product createProduct() {
return new ConcreteProduct1();
}
}
class ConcreteFactory2 implements Factory {
@Override
public Product createProduct() {
return new ConcreteProduct2();
}
}
// 测试类
public class FactoryMethodDemo {
public static void main(String[] args) {
Factory factory1 = new ConcreteFactory1();
Product product1 = factory1.createProduct();
product1.show();
Factory factory2 = new ConcreteFactory2();
Product product2 = factory2.createProduct();
product2.show();
}
}
抽象工厂模式(Abstract Factory Pattern):又称为工具箱模式,它提供一个创建一系列相关或依赖对象的接口,而无需指定它们具体的类。抽象工厂模式将一组相关的产品类集合在一起进行创建,但不需要指定具体的类。抽象工厂模式可以将一个产品族的产品创建在一起,因此可以保证一组产品的一致性。但它的扩展性不如工厂方法模式。
// 创建产品接口
interface Product1 {
void show();
}
interface Product2 {
void show();
}
// 创建具体产品类
class ConcreteProduct1 implements Product1 {
@Override
public void show() {
System.out.println("具体产品1");
}
}
class ConcreteProduct2 implements Product2 {
@Override
public void show() {
System.out.println("具体产品2");
}
}
// 创建工厂接口
interface Factory {
Product1 createProduct1();
Product2 createProduct2();
}
// 创建具体工厂类
class ConcreteFactory1 implements Factory {
@Override
public Product1 createProduct1() {
return new ConcreteProduct1();
}
@Override
public Product2 createProduct2() {
return new ConcreteProduct2();
}
}
class ConcreteFactory2 implements Factory {
@Override
public Product1 createProduct1() {
return new ConcreteProduct1();
}
@Override
这些工厂模式在实际应用中有着广泛的应用。简单工厂模式适用于简单的对象创建场景,工厂方法模式适用于产品等级较为复杂的场景,而抽象工厂模式适用于产品族的创建。开发人员需要根据实际情况进行选择和应用。
4.建造者模式
建造者模式是一种创建型设计模式,它可以将复杂对象的创建过程拆分成多个简单的步骤,从而使得代码更加清晰,易于维护和扩展。与简单工厂、工厂方法和抽象工厂不同,建造者模式着重于创建对象的复杂构建过程,而不是只关注对象的创建。
建造者模式可以分为以下几个角色:
-
产品类(Product):定义需要被建造的对象。
-
抽象建造者类(Builder):定义建造产品的抽象接口,包含多个建造产品的抽象方法。
-
具体建造者类(ConcreteBuilder):实现抽象建造者接口,完成具体产品的构建过程。
-
指挥者(Director):调用建造者接口,按照特定顺序构建产品。
// 创建产品类
class Product {
private String partA;
private String partB;
private String partC;
public String getPartA() {
return partA;
}
public void setPartA(String partA) {
this.partA = partA;
}
public String getPartB() {
return partB;
}
public void setPartB(String partB) {
this.partB = partB;
}
public String getPartC() {
return partC;
}
public void setPartC(String partC) {
this.partC = partC;
}
@Override
public String toString() {
return "Product{" +
"partA='" + partA + '\'' +
", partB='" + partB + '\'' +
", partC='" + partC + '\'' +
'}';
}
}
// 创建抽象建造者类
abstract class Builder {
public abstract void buildPartA();
public abstract void buildPartB();
public abstract void buildPartC();
public abstract Product getResult();
}
// 创建具体建造者类
class ConcreteBuilder extends Builder {
private Product product = new Product();
@Override
public void buildPartA() {
product.setPartA("PartA");
}
@Override
public void buildPartB() {
product.setPartB("PartB");
}
@Override
public void buildPartC() {
product.setPartC("PartC");
}
@Override
public Product getResult() {
return product;
}
}
// 创建指挥者类
class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public void construct() {
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
}
}
// 测试类
public class BuilderDemo {
public static void main(String[] args) {
Builder builder = new ConcreteBuilder();
Director director = new Director(builder);
director.construct();
Product product = builder.getResult();
System.out.println(product);
}
}
在这个示例中,我们创建了一个产品类(Product),它包含了多个组成部分,我们使用建造者模式来创建这个复杂对象。首先,我们定义了一个抽象建造者类(Builder),其中包含了多个抽象方法,用于定义具体的建造过程。然后,我们定义了一个具体建造者类(ConcreteBuilder),它实现了抽象建造者接口,并完成了具体的建造过程。最后,我们创建了一个指挥者(Director)类,它使用建造者接口来创建具体产品,并按照特定顺序调用建造者接口中的方法。在测试类中,我们创建了一个具体的建造者对象,然后使用指挥者对象来调用建造者接口中的方法,从而创建了一个包含多个组成部分的复杂对象。
建造者模式在实际项目中的应用非常广泛,特别是在创建复杂对象时。例如,在Java中,StringBuilder类就是使用建造者模式来创建字符串对象的。在Spring框架中,也有很多应用建造者模式的例子,例如XmlBeanDefinitionReader类就是使用建造者模式来创建BeanDefinition对象的。
总之,建造者模式可以帮助我们将复杂对象的创建过程拆分成多个简单的步骤,从而使得代码更加清晰、易于维护和扩展。它可以避免在代码中使用大量的构造器或者setter方法,从而提高代码的可读性和可维护性。
5.原型模式
原型模式(Prototype Pattern)是一种创建型设计模式,它可以通过复制现有对象来创建新的对象,而无需重新实例化。原型模式通常适用于创建复杂对象或者创建过程比较耗时的情况,通过复制已有对象的方式来创建新对象可以提高创建效率,同时也避免了重复创建相似对象的问题。
// 定义一个原型接口
public interface Prototype {
Prototype clone();
}
// 定义一个具体的原型类
public class ConcretePrototype implements Prototype {
private String name;
public ConcretePrototype(String name) {
this.name = name;
}
public Prototype clone() {
return new ConcretePrototype(name);
}
public String getName() {
return name;
}
}
// 定义一个客户端类
public class Client {
public static void main(String[] args) {
Prototype prototype = new ConcretePrototype("原型对象");
Prototype clone = prototype.clone();
System.out.println("原型对象的名称:" + prototype.getName());
System.out.println("克隆对象的名称:" + clone.getName());
}
}
在上面的demo中,我们首先定义了一个原型接口(Prototype),其中包含了一个克隆方法(clone),用于复制当前对象并创建一个新的对象。然后,我们定义了一个具体的原型类(ConcretePrototype),它实现了原型接口并完成了具体的克隆过程。最后,我们创建了一个客户端类(Client),它通过调用原型对象的克隆方法来创建一个新的对象,并输出了原型对象和克隆对象的名称。
原型模式在实际项目中的应用也非常广泛,例如,在Java中,Object类就是所有类的根类,它提供了一个clone方法,可以通过复制现有对象来创建新对象。在Spring框架中,也有很多应用原型模式的例子,例如,在创建Bean时,Spring会先创建一个原型对象,然后通过复制原型对象来创建多个相似的Bean对象。
总之,原型模式可以帮助我们快速创建复杂对象,从而提高代码的效率和可维护性。同时,它也避免了在代码中重复创建相似对象的问题,从而减少了内存的开销。
6.单例模式
单例模式(Singleton Pattern)是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例。
单例模式有很多种实现方式,下面我们介绍其中比较常用的两种方式。
饿汉式单例模式
饿汉式单例模式是一种最简单的实现方式,它在类加载时就创建了单例对象,因此也被称为静态单例模式。下面是一个简单的饿汉式单例模式的示例代码:
public class Singleton {
// 私有化构造函数,确保外部无法实例化该类
private Singleton() {
}
// 定义静态的单例对象
private static Singleton instance = new Singleton();
// 提供公共的访问方法,用于获取单例对象
public static Singleton getInstance() {
return instance;
}
}
在上面的示例代码中,我们定义了一个Singleton类,其中包含一个私有化的构造函数,确保外部无法实例化该类。然后,我们定义了一个静态的单例对象instance,并在类加载时就创建了该对象。最后,我们提供了一个公共的访问方法getInstance,用于获取单例对象。
懒汉式单例模式
public class Singleton {
// 私有化构造函数,确保外部无法实例化该类
private Singleton() {
}
// 定义静态的单例对象
private static Singleton instance;
// 提供公共的访问方法,用于获取单例对象
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
懒汉式单例模式是一种延迟加载的实现方式,它在第一次调用getInstance方法时才创建单例对象。下面是一个简单的懒汉式单例模式的示例代码:
public class Singleton {
// 私有化构造函数,确保外部无法实例化该类
private Singleton() {
}
// 定义静态的单例对象
private static Singleton instance;
// 提供公共的访问方法,用于获取单例对象
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
在上面的示例代码中,我们同样定义了一个Singleton类,并私有化了构造函数。不同的是,我们没有在类加载时就创建单例对象,而是在getInstance方法中进行判断,如果instance为null,则创建一个新的单例对象,否则直接返回已有的单例对象。
单例模式在实际项目中也是应用非常广泛的设计模式,例如,在Java中,Runtime类就是一个单例类,它提供了一个公共的访问点来获取唯一的实例。在Spring框架中,也有很多应用单例模式的例子,例如,BeanFactory就是一个单例类,它负责管理所有的Bean对象。
总之,单例模式可以帮助我们确保一个类只有一个实例,避免了在代码中重复创建相同对象的问题,从而减少了内存的开销,同时也提高了代码的可