设计模式 笔记1 | 五个创建型模式 | Java 语言实现 | 工厂方法设计模式 | 抽象工厂模式 |建造者模式 | 单例模式 | 原型模式

本文详细介绍了Java中的五个创建型设计模式:工厂方法、抽象工厂、建造者、单例和原型模式。从模式定义、优缺点、应用场景及主要组成等方面展开,通过代码模板展示了每个模式的实现方式,并提供了应用案例。文章旨在帮助读者深入理解并掌握这些设计模式的使用。
摘要由CSDN通过智能技术生成


在使用设计模式前,我们先用常见的方法来实现封装水果类,以及水果的继承类苹果和橘子

  1. 定义一个水果抽象类
public abstract class Fruit {
       // 水果抽象类
    private final String name;

    public Fruit(String name){
   
        this.name = name;
    }

    @Override
    public String toString() {
   
        return name + "@" + hashCode(); // 打印当前水果名称和 哈希值
    }
}
  1. 定义实现的子类
// 苹果
class Apple extends Fruit{
   
    public Apple(){
   
        super("苹果");
    }
}
// 橘子
class Origin extends Fruit{
   
    public Origin(){
   
        super("橘子");
    }
}

  1. 运行测试
public class Demo {
   
    public static void main(String[] args) {
   
        System.out.println(new Apple());
        System.out.println(new Origin());
    }
}
// 输出结果
// 苹果@685325104
// 橘子@460141958

接下来我们通过一些设计模式来改写上面的例子,以便体会不同设计模式的特点。

一、工厂方法设计模式


工厂模式定义:定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体工厂类中。

在学习工厂方法设计模式前,我们先了解了解简单的工厂模式,简单工厂模式不归属于23种设计模式中。

在简单工厂模式中创建实例的方法通常为静态(static)方法,因此简单工厂模式又称为静态工厂方法模式。

优点:

  • 使得工厂和产品区分明确
  • 客户无需知道所需创建具体产品的类名,只需知道参数

缺点:

  • 扩展性差,增加新产品时不得不修改工作逻辑。
  • 简单工厂模式会增加系统中类的个数,增加系统的复杂性和理解难度
  • 简单工厂模式使用了 static 工厂方法,无法实现继承
  • 违背了开闭原则

应用场景:
产品种类相对较少时,可以考虑使用简单工厂模式。
主要组成:

  • 简单工厂(SimpleFactory),是简单工厂模式的核心,负责实现创建所有实例的内部逻辑,工厂类创建产品类的方法可以被外界直接调用,创建所需的产品对象
  • 抽象产品(Product),是简单工厂创建所有对象的父类,负责描述所有实例共有的公共接口
  • 具体产品(Concrete Product),是简单工厂模式的创建目标

模板代码:

// 简单工厂模式
public class Demo{
   
    // 抽象产品
    interface Product{
   
        void show();
    }
    // 具体产品: Product A
    static class ConcreteProduct1 implements Product{
   

        @Override
        public void show() {
   
            System.out.println("具体产品1显示");
        }
    }
    // 具体产品: Product B
    static class ConcreteProduct2 implements Product{
   

        @Override
        public void show() {
   
            System.out.println("具体产品2显示");
        }
    }
    // 标记产品
    final class Const{
   
        final static int A = 0;
        final static int B = 1;
    }
    static class SimpleFactory{
   
        public static Product makeProduct(int type){
   
            switch (type){
   
                case Const.A:
                    return new ConcreteProduct1();
                case Const.B:
                    return new ConcreteProduct2();
            }
            return null;
        }
    }

    public static void main(String[] args) {
   
        Product productA = SimpleFactory.makeProduct(Const.A);
        Product productB = SimpleFactory.makeProduct(Const.B);
        assert productA != null;
        productA.show();
        assert productB != null;
        productB.show();
    }
}

工厂方法模式定义:是对简单工厂模式的进一步抽象化,符合开闭原则

优点:

  • 用户只需知道具体工厂名称就可以获得需要的产品,无须知道产品的具体创建过程
  • 灵活性强,对于新产品创建,只需多写一个相应的工厂类
  • 解耦合,符合迪米特法则、依赖倒置原则和里氏替换原则

缺点:

  • 类个数容易增多,增加复杂度
  • 增加了系统的抽象性和理解难度
  • 抽象产品只能生产一种产品(可使用抽象工厂模式解决)

应用场景:

  • 用户只需知道产品的工厂名,而不知道具体的产品名
  • 创建对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口

1.1 主要组成与模板代码

主要组成:

  • 抽象工厂(Abstract Factory),提供了创建产品的接口,调用者通过它访问具体的工厂方法 newProduct() 来创建产品
  • 具体工厂(ConcreteFactory),主要是实现抽象工厂中的抽象方法,完成具体产品的创建
  • 抽象产品(Product),定义了产品的规范,描述了产品的主要特性和功能
  • 具体产品(ConcreteProduct),实现了抽象产品角色所定义的接口,由具体的工厂创建

模板代码:

// 工厂方法模式
// 抽象产品
interface Product{
   
    public void show();
}
// 具体产品 1: 实现抽象产品中的抽象方法
class ConcreteProduct1 implements Product{
   
    @Override
    public void show() {
   
        System.out.println("具体产品1 展示");
    }
}
// 具体产品2: 实现抽象产品中的抽象方法
class ConcreteProduct2 implements Product{
   

    @Override
    public void show() {
   
        System.out.println("具体产品2 显示");
    }
}
// 抽象工厂
interface AbstractFactory{
   
    public Product newProduct();
}
// 具体工厂1 : 实现了产品1的生成方法
class ConcreteFactory1 implements AbstractFactory{
   

    @Override
    public Product newProduct() {
   
        System.out.println("具体工厂1生成 --> 具体产品1...");
        return new ConcreteProduct1();
    }
}
// 具体工厂2: 实现了产品2的生成方法
class ConcreteFactory2 implements AbstractFactory{
   
    @Override
    public Product newProduct() {
   
        System.out.println("具体工厂2生成 --> 具体产品2...");
        return new ConcreteProduct2();
    }
}
public class Demo{
   
    public static void main(String[] args) {
   
        ConcreteFactory1 factory1 = new ConcreteFactory1();
        ConcreteFactory2 factory2 = new ConcreteFactory2();
        Product product1 = factory1.newProduct();
        Product product2 = factory2.newProduct();
        product1.show();
        product2.show();
    }
}

1.2 应用案例

基于之前水果的例子,我们使用抽象类+泛型,将水果工厂类进一步划分成具体的水果工厂类

public abstract class FruitFactory<T extends Fruit> {
   
    public abstract T getFruit();
}

class AppleFactory extends FruitFactory<Apple>{
   
    @Override
    public Apple getFruit() {
   
        return new Apple();
    }
}
class OriginFactory extends FruitFactory&l
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值