设计模式学习笔记2(创建型模式)

本文详细介绍了四种常见设计模式:单例模式确保类只有一个实例,降低系统耦合;原型模式通过复制已有对象创建新对象,优化资源访问;工厂方法模式提供创建对象的接口,提高系统扩展性;建造者模式则将复杂对象构建与表示分离,使得构建过程可定制化。每种模式都有其优缺点及应用场景,并提供了相应的Java实现示例。
摘要由CSDN通过智能技术生成

创建型

关注点是’怎样创建对象’,主要是将对象的创建与使用分离,降低系统的耦合度,使用户不需要关注对象的创建细节。

单列模式
概述

在全局范围下,一个类只存在一个实例对象

优缺点

优点:

  • 保存内存中只有一个实例,减少内存开销
  • 可以避免对资源的多重占用
  • 可设置全局访问点,可以优化和共享资源的访问

缺点:

  • 非面向抽象编程,扩展性低
  • 并发测试中不利于调试
实现
  • 饿汉式单列
/**
 * 单列对象
 */
public class Singleton{
    private static final  Singleton singleton = new Singleton();
    private String name;
    private Integer age;
    //此处省略get\set方法
    //私有化构造方法
    private Singleton(){}
    
    public static Singleton getInstance(){
        return singleton;
    }
}
  • 懒汉式单例
public class Singleton{
    //使用volatile保证线程的可见性
    private static volatile  Singleton singleton = null;
    private String name;
    private Integer age;
    //此处省略get\set方法

    //私有化构造方法
    private Singleton(){}

    public static Singleton getInstance(){
        //使用双重检查,防止实例重复创建
        if(singleton == null){
            synchronized (Singleton.class){
                if(singleton = null){
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}
原型模式
概述

用一个已创建的实例作为原型,通过复制该实例对象生成一个新对象,且该新对象具有与原型对象相同的数据内容

优缺点

优点:

  • java自带的原型模式是基于内存二进制流的复制,相对直接new一个新对象性能更好
  • 由于新对象基于原型对象,与原型对象具有相同的数据,可以在需要的时候恢复到初始值
  • 简化了创建对象并设置初始值的过程

缺点:

  • 需要为每个类都新增一个clone方法
  • 每次改造类后都需要修改原有代码,降低了扩展性
  • 当对象内组合了其他复杂对象且要实现深克隆时,需要编写更为复杂的代码

注:
浅克隆:创建新对象是,新对象和原型对象数据完全相同,对于引用数据类型的内存地址与原型对象一样
深克隆:创建新对象是,新对象和原型对象的基本数据类型完全相同,但引用对象也会被克隆,引用数据类型的内存地址不指向原有对象地址

实现
  • 浅克隆
import java.util.Arrays;
/**
 * 原型类,要克隆需要实现Cloneable接口
 */
public class Prototype implements Cloneable {

    private List<String> hobby;
    public void setHobby(List<String> hobby) {this.hobby = hobby;}
    public List<String> getHobby() {return hobby;}

    public Prototype() {}

    public Object clone() throws CloneNotSupportedException {
        return (Prototype) super.clone();
    }

    public static void main(String[] args)  throws CloneNotSupportedException {
        //创建原型对象
        Prototype prototype = new Prototype();
        prototype.setHobby(Arrays.asList("篮球", "读书", "看美女"));
        //基于原型对象创建新对象
        Prototype clone = (Prototype) prototype.clone();
        System.out.println("prototype == clone:"+(prototype == clone));//false
        System.out.println("prototype.hobby == clone.hobby:"+(prototype.getHobby() == clone.getHobby()));//true
    }
}
  • 深克隆
import java.util.ArrayList;
import java.util.Arrays;

/**
 * 原型类,要克隆需要实现Cloneable接口
 */
public class Prototype implements Cloneable {

    private List<String> hobby;
    public void setHobby(List<String> hobby) {this.hobby = hobby;}
    public List<String> getHobby() {return hobby;}
    public Prototype() {}
    
    public Object clone() throws CloneNotSupportedException {
        Prototype clone = (Prototype) super.clone();
        //新建一个对象再重新赋值给克隆对象
        List<String> newHobby = new ArrayList<>();
        newHobby.addAll(clone.getHobby());
        clone.setHobby(newHobby);
        return clone;
    }
    public static void main(String[] args) {
        //创建原型对象
        Prototype prototype = new Prototype();
        prototype.setHobby(Arrays.asList("篮球", "读书", "看美女"));
        //基于原型对象创建新对象
        Prototype clone = (Prototype) prototype.clone();
        System.out.println("prototype == clone:" + (prototype == clone));//false
        System.out.println("prototype.hobby == clone.hobby:"+(prototype.getHobby() == clone.getHobby()));//false
    }
}
工厂方法模式
概述

定义一个用于创建产品的接口,由子类决定生产什么产品。

优缺点

优点:

  • 降低了系统框架的耦合程度
  • 提高了系统的可扩展性

缺点:

  • 增加了系统的复杂度和类的个数
  • 工厂只能生产一种产品。可以通过抽象工厂模式解决
实现
/**
 * 抽象产品
 */
public interface Fruit {
    void show();
}
/**
 * 具体产品
 */
public class Apple implements Fruit{
    @Override
    public void show() {
        System.out.println("这是苹果");
    }
}
public class Banana implements Fruit{
    @Override
    public void show() {
        System.out.println("这是香蕉");
    }
}

/**
 * 抽象工厂:
 *  提供了厂品的生成方法
 */
public interface AbstractFactory {
    /**
     * 抽象方法,子类工厂可重写此方法创建产品
     * @return
     */
    Fruit newProduct();
}
/**
 * 具体工厂,用来生产Apple
 */
public class AppleFactory implements AbstractFactory{
    @Override
    public Fruit newProduct() {
        return new Apple();
    }
}
/**
 * 具体工厂,用来生产Banana
 */
public class BananaFactory implements AbstractFactory{
    @Override
    public Fruit newProduct() {
        return new Banana();
    }
}
抽象工厂模式
概述

与工厂方法模式相差不大,只是一个工厂存在多个方法,能创建出配套的一系列产品

建造者模式
概述

将一个复杂对象的创建于表示分离,使同样的构建过程可以创建不同的部分

优缺点

优点:

  • 封装性好,构建和表示分离
  • 扩展性好,各个具体的构建相互独立,降低了系统的耦合度
  • 将构建过程细化

缺点:

  • 由于组成部分必须相同导致使用范围有限
  • 不符合开闭原则,内部代码修改,建造者也得修改
实现
/**
 * 具体产品:人类
 */
public class Human {
    private String header;
    private String hands;
    private String foot;
    public String getHeader() {
        return header;
    }
    public void setHeader(String header) {
        this.header = header;
    }
    public String getHands() {
        return hands;
    }
    public void setHands(String hands) {
        this.hands = hands;
    }
    public String getFoot() {
        return foot;
    }
    public void setFoot(String foot) {
        this.foot = foot;
    }
    @Override
    public String toString() {
        return "Human{" +
                "header='" + header + '\'' +
                ", hands='" + hands + '\'' +
                ", foot='" + foot + '\'' +
                '}';
    }
}
/**
 * 人类抽象建造者
 */
public interface HumanBuilder {
    /**
     * 构建头部
     */
    void builderHeader();
    /**
     * 构建手部
     */
    void builderHands();
    /**
     * 构建足部
     */
    void builderFoot();
    /**
     * 返回结果
     * @return
     */
    Human getResult();
}
/**
 * 黑人具体建造者
 */
public class BlackHumanBuilder implements HumanBuilder{

    private Human human;

    public BlackHumanBuilder(){
        human = new Human();
    }

    @Override
    public void builderHeader() {
        human.setHeader("黑人头部构建成功");
    }

    @Override
    public void builderHands() {
        human.setHands("黑人手部构建成功");
    }

    @Override
    public void builderFoot() {
        human.setFoot("黑人足部构建成功");
    }

    @Override
    public Human getResult() {
        return human;
    }
}
/**
 * 白人具体建造者
 */
public class WhiteHumanBuilder implements HumanBuilder{

    private Human human;

    public WhiteHumanBuilder(){
        human = new Human();
    }

    @Override
    public void builderHeader() {
        human.setHeader("白人头部构建成功");
    }

    @Override
    public void builderHands() {
        human.setHands("白人手部构建成功");
    }

    @Override
    public void builderFoot() {
        human.setFoot("白人足部构建成功");
    }

    @Override
    public Human getResult() {
        return human;
    }
}
/**
 * 指挥者对象
 */
public class Director {

    private HumanBuilder builder;

    private Director(HumanBuilder builder){
        this.builder = builder;
    }

    /**
     * 产品构建
     * @return
     */
    public Human construct(){
        builder.builderHeader();
        builder.builderHands();
        builder.builderFoot();
        return builder.getResult();
    }

    public static void main(String[] args) {
        WhiteHumanBuilder whiteHumanBuilder = new WhiteHumanBuilder();
        Director director = new Director(whiteHumanBuilder);
        Human human = director.construct();
        System.out.println(human);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值