23种设计模式_MODE05原型模式_手写代码实现

简介: 23种设计模式_MODE05原型模式_手写代码实现

1.原型模式测试 == 两种方式,你选哪一种?

package com.zhaoshuangjian.mode05_原型模式;
import com.zhaoshuangjian.mode05_原型模式.mode05.HomeWork;
import com.zhaoshuangjian.mode05_原型模式.mode05.PupilStudent;
import com.zhaoshuangjian.mode05_原型模式.mode05.SexEnum;
import com.zhaoshuangjian.mode05_原型模式.mode05.WorkTypeEnum;
import com.zhaoshuangjian.utils.DateUtils;
import java.util.Date;
/**
 * <p>原型模式测试 == 两种方式,你选哪一种?</p>
 *
 * @Author zhaoshuangjian  2023-03-23 下午10:39
 */
public class PrototypeTest {
    public static void main(String[] args) throws CloneNotSupportedException{
        // 原型 == 我们创建一个已经由小学生【刘晓然】完成的作业对象
        HomeWork homeWork = new HomeWork();
        // 设置作业信息
        homeWork.setType(WorkTypeEnum.WULI);
        homeWork.setPages(12);
        homeWork.setFinishTime(new Date());
        // 设置小学生信息 == 刘晓然
        PupilStudent pupilStudent  = new PupilStudent();
        pupilStudent.setsNo(1001L);
        pupilStudent.setName("刘晓然");
        pupilStudent.setAge(10);
        pupilStudent.setSex(SexEnum.FEMALE);
        pupilStudent.setsClass(4);
        homeWork.setPupilStudent(pupilStudent);
        // 1、原型模式第一种 == 作业对象浅拷贝测试
        HomeWork ykHomeWork = shallowCopy(homeWork);
        System.out.println("刘晓然的作业:\n"+homeWork);
        System.out.println("我的作业:\n"+ykHomeWork);
        /**
         * 以上输出结果为:
         * 刘晓然的作业:
         * 类型:物理,页数:12,完成时间:2023年03月22日 14时03分45秒,完成者:zhaoshuangjian,学号:1002,年级:4,年龄:10,性别:男
         * 我的作业:
         * 类型:物理,页数:12,完成时间:2023年03月23日 14时03分45秒,完成者:zhaoshuangjian,学号:1002,年级:4,年龄:10,性别:男
         *
         * 纳尼???
         * 老师:"刘晓然同学,你说,你作业是不是抄别人的?为什么你的作业和zhaoshuangjian同学的作业一模一样!!!"
         * 刘晓然:"老师,我自己做的,我没有抄啊,哭哭哭......"
         * zhaoshuangjian:"我去,这,什么情况?我不是都改了吗,啊啊啊啊啊......"
         */
        // 2、原型模式第二种 == 作业对象深拷贝测试
        System.out.println("=========================================分割线=========================================");
        /**
         * 假设有第三个同学,要抄作业,这个同学假设叫"张聪明"
         * 他怎么聪明呢?我们看下面的案列
         */
        HomeWork zhangHomeWork = deepCopy(ykHomeWork);
        System.out.println("zhaoshuangjian的作业:\n"+ykHomeWork);
        System.out.println("张聪明的作业:\n"+zhangHomeWork);
        /**
         * 以上输出结果为:
         * zhaoshuangjian的作业:
         * 类型:物理,页数:12,完成时间:2023年03月23日 14时16分11秒,完成者:zhaoshuangjian,学号:1002,年级:4,年龄:10,性别:男
         * 张聪明的作业:
         * 类型:物理,页数:12,完成时间:2023年03月23日 14时16分11秒,完成者:张聪明,学号:1003,年级:4,年龄:10,性别:男
         *
         *
         * 老师:"张聪明同学,你的作业完成的很棒吗!"
         * 张聪明:"哈哈,果然这种抄作业的方式很完美,完全没有漏洞"
         * 老师:"刘晓然和zhaoshuangjian,你们俩放学留一下,不讲清楚你俩作业怎么回事,我就叫你们家长过来!"
         * 刘晓然:"老师,我是真没抄啊,我都不知道发生了什么啊,呜呜呜呜..."
         * zhaoshuangjian:"卧槽,我再也不干这种伤天害理的事情了,我下一次一定要深度抄作业!!!!"
         */
    }
    /**
     * 对象浅拷贝
     * @param homeWork
     * @return
     * @throws CloneNotSupportedException
     */
    public static  HomeWork shallowCopy(HomeWork homeWork) throws  CloneNotSupportedException{
        /**
         *  独白:
         *  (1)复制一份【刘晓然】的作业
         *  (2)将复制过来的作业改成我自己的,记住,信息全改,不然被老师发现了,我还在"三好学生"堆里面怎么混
         *  (3)我以为自己耍了个小聪明,擅自改作业,却不知"尴尬"却正在发生....
         */
        HomeWork myHomeWork = homeWork.clone();
        // 开始改造  == 首先改完成时间
        myHomeWork.setFinishTime(DateUtils.addDays(1));
        // 然后改作业的完成者,就是我 == 【zhaoshuangjian】
        PupilStudent mySelf = myHomeWork.getPupilStudent();
        // 学号肯定不能一样吧,不然这还不被发现作业是抄的吗
        mySelf.setsNo(1002L);
        // 我去,还要改名字,这事我差点忘了
        mySelf.setName("zhaoshuangjian");
        // 性别,对,还有性别,这个不能粗心大意,忘改了
        mySelf.setSex(SexEnum.MALE);
        // OK,一切就绪,改的那叫一个相当顺利啊,哈哈哈哈! == 满心欢喜交作业咯
        return  myHomeWork;
    }
    /**
     * 对象深度拷贝
     * @param homeWork
     * @return
     * @throws CloneNotSupportedException
     */
    public static  HomeWork deepCopy(HomeWork homeWork) throws  CloneNotSupportedException{
        /**
         *  独白:
         *  (1)复制一份【zhaoshuangjian】的作业
         *  (2)因为是深度拷贝,抄的比较认真,比较深,雪下的那么认真.....
         *  (3)因此,我完全不必担心,老师会发现端倪,哈哈哈哈哈哈.....
         */
        HomeWork myHomeWork = homeWork.deepClone();
        // 开始改造  == 首先改完成时间,完成时间+1天
        myHomeWork.setFinishTime(DateUtils.addDays(1));
        PupilStudent mySelf = myHomeWork.getPupilStudent();
        mySelf.setsNo(1003L);
        mySelf.setName("张聪明");
        mySelf.setSex(SexEnum.MALE);
        return  myHomeWork;
    }
}

2.小学生的家庭作业

package com.zhaoshuangjian.mode05_原型模式.mode05;
import com.zhaoshuangjian.utils.DateUtils;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.*;
import java.util.Date;
/**
 * <p>小学生的家庭作业</p>
 *
 * @Author zhaoshuangjian  2023-03-23 下午10:39
 */
public class HomeWork implements  Cloneable,Serializable {
  private static final long serialVersionUID = 1L;
  /**
     * 作业类型
     */
    private com.zhaoshuangjian.mode05_原型模式.mode05.WorkTypeEnum type = com.zhaoshuangjian.mode05_原型模式.mode05.WorkTypeEnum.YUWEN;
    /**
     * 完成时间
     */
    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private Date finishTime ;
    /**
     * 作业页码数【作业量】
     */
    private Integer pages = 0;
    /**
     * 完成者
     */
    private com.zhaoshuangjian.mode05_原型模式.mode05.PupilStudent pupilStudent;
    public HomeWork(){
    }
    public com.zhaoshuangjian.mode05_原型模式.mode05.WorkTypeEnum getType() {
        return type;
    }
    public void setType(com.zhaoshuangjian.mode05_原型模式.mode05.WorkTypeEnum type) {
        this.type = type;
    }
    public Date getFinishTime() {
        return finishTime;
    }
    public void setFinishTime(Date finishTime) {
        this.finishTime = finishTime;
    }
    public Integer getPages() {
        return pages;
    }
    public void setPages(Integer pages) {
        this.pages = pages;
    }
    public com.zhaoshuangjian.mode05_原型模式.mode05.PupilStudent getPupilStudent() {
        return pupilStudent;
    }
    public void setPupilStudent(com.zhaoshuangjian.mode05_原型模式.mode05.PupilStudent pupilStudent) {
        this.pupilStudent = pupilStudent;
    }
    /**
     * 对象浅拷贝  == 对象中按值类型传递部分均能完美拷贝走,但是按引用类型传递部分则拷贝不走
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    public com.zhaoshuangjian.mode05_原型模式.mode05.HomeWork clone() throws CloneNotSupportedException {
        return (com.zhaoshuangjian.mode05_原型模式.mode05.HomeWork) super.clone();
    }
    /**
     * 深度拷贝 == 不管你对象中是值类型部分,还是引用类型部分,我全部拿走
     * 对象字节流的序列与反序列化 ==> 对象完全、深度、彻彻底底的Copy!!!
     * @return
     */
    public com.zhaoshuangjian.mode05_原型模式.mode05.HomeWork deepClone(){
        // Anything 都是可以用字节流进行表示,记住是任何!
        com.zhaoshuangjian.mode05_原型模式.mode05.HomeWork homeWork = null;
        try{
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            // 将当前的对象写入baos【输出流 -- 字节数组】里
            oos.writeObject(this);
            // 从输出字节数组缓存区中拿到字节流
            byte[] bytes = baos.toByteArray();
            // 创建一个输入字节数组缓冲区
            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
            // 创建一个对象输入流
            ObjectInputStream ois = new ObjectInputStream(bais);
            // 下面将反序列化字节流 == 重新开辟一块空间存放反序列化后的对象
            homeWork = (com.zhaoshuangjian.mode05_原型模式.mode05.HomeWork) ois.readObject();
        }catch (Exception e){
            System.out.println(e.getClass()+":"+e.getMessage());
        }
        return  homeWork;
    }
    @Override
    public String toString() {
        return  String.format("类型:%s,页数:%s,完成时间:%s," +
                "完成者:%s,学号:%d,年级:%d,年龄:%d,性别:%s",this.type.getName()
                ,this.pages,DateUtils.dateTostring(this.finishTime),this.pupilStudent.getName(),
                this.pupilStudent.getsNo(),this.pupilStudent.getsClass(),
                this.pupilStudent.getAge(),this.pupilStudent.getSex().getName());
    }
}

3.小学生 == 如果要实现对象的深度拷贝,嵌套引用类型的对象类必须也实现Serializable接口

package com.zhaoshuangjian.mode05_原型模式.mode05;
import java.io.Serializable;
/**
 * <p>小学生 == 如果要实现对象的深度拷贝,嵌套引用类型的对象类必须也实现Serializable接口</p>
 *
 * @Author zhaoshuangjian  2023-03-23 下午10:39
 */
public class PupilStudent implements Serializable {
  private static final long serialVersionUID = 1L;
  /**
     * 学号
     */
    private Long sNo;
    /**
     * 年级
     */
    private Integer sClass;
    /**
     * 姓名
     */
    private String name;
    /**
     * 年龄
     */
    private Integer age;
    /**
     * 性别
     */
    private SexEnum sex = SexEnum.MALE;
    public  PupilStudent(){
    }
    public Long getsNo() {
        return sNo;
    }
    public void setsNo(Long sNo) {
        this.sNo = sNo;
    }
    public Integer getsClass() {
        return sClass;
    }
    public void setsClass(Integer sClass) {
        this.sClass = sClass;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public SexEnum getSex() {
        return sex;
    }
    public void setSex(SexEnum sex) {
        this.sex = sex;
    }
}

4.性别枚举类

package com.zhaoshuangjian.mode05_原型模式.mode05;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
/**
 * <p>性别枚举类</p>
 *
 * @Author zhaoshuangjian  2023-03-23 下午10:39
 */
public enum SexEnum {
    /**
     * 枚举对象
     */
    MALE("男",0),
    FEMALE("女",1);
    private final  String name ;
    private final  Integer value;
    /**
     * 枚举构造器
     * @param name 性别名称
     * @param value 性别值
     */
    SexEnum(String name,Integer value){
        this.name = name;
        this.value = value;
    }
    /**
     * 通过name获取对应的枚举对象
     * @param name 类型名称
     * @return
     */
    public static com.zhaoshuangjian.mode05_原型模式.mode05.SexEnum getEnum(String name){
        for(com.zhaoshuangjian.mode05_原型模式.mode05.SexEnum sexEnum : com.zhaoshuangjian.mode05_原型模式.mode05.SexEnum.values()){
            if(name.equals(sexEnum.getName())){
                return  sexEnum;
            }
        }
        return  null;
    }
    /**
     * 通过value获取对应的枚举对象
     * @param value 类型值
     * @return
     */
    @JsonCreator
    public static com.zhaoshuangjian.mode05_原型模式.mode05.SexEnum getEnum(Integer value){
        for(com.zhaoshuangjian.mode05_原型模式.mode05.SexEnum sexEnum : com.zhaoshuangjian.mode05_原型模式.mode05.SexEnum.values()){
            if(value.equals(sexEnum.getValue())){
                return  sexEnum;
            }
        }
        return  null;
    }
    public String getName() {
        return name;
    }
    @JsonValue
    public Integer getValue() {
        return value;
    }
}

5.作业枚举类

package com.zhaoshuangjian.mode05_原型模式.mode05;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
/**
 * <p>作业枚举类</p>
 *
 * @Author zhaoshuangjian  2023-03-23 下午10:39
 */
public enum WorkTypeEnum {
    /**
     * 枚举对象
     */
    YUWEN("语文",0),
    SHUXUE("数学",1),
    YINGYU("英语",2),
    WULI("物理",3),
    HUAXUE("化学",4),
    SHENGWU("生物",5);
    private final  String name ;
    private final  Integer value;
    /**
     * 枚举构造器
     * @param name 作业类型名称
     * @param value 作业类型值
     */
    WorkTypeEnum(String name,Integer value){
        this.name = name;
        this.value = value;
    }
    /**
     * 通过name获取对应的枚举对象
     * @param name 类型名称
     * @return
     */
    public static com.zhaoshuangjian.mode05_原型模式.mode05.WorkTypeEnum getEnum(String name){
        for(com.zhaoshuangjian.mode05_原型模式.mode05.WorkTypeEnum typeEnum : com.zhaoshuangjian.mode05_原型模式.mode05.WorkTypeEnum.values()){
            if(name.equals(typeEnum.getName())){
                return  typeEnum;
            }
        }
        return  null;
    }
    /**
     * 通过value获取对应的枚举对象
     * @param value 类型值
     * @return
     */
    @JsonCreator
    public static com.zhaoshuangjian.mode05_原型模式.mode05.WorkTypeEnum getEnum(Integer value){
        for(com.zhaoshuangjian.mode05_原型模式.mode05.WorkTypeEnum typeEnum : com.zhaoshuangjian.mode05_原型模式.mode05.WorkTypeEnum.values()){
            if(value.equals(typeEnum.getValue())){
                return  typeEnum;
            }
        }
        return  null;
    }
    public String getName() {
        return name;
    }
    @JsonValue
    public Integer getValue() {
        return value;
    }
}



相关文章
|
2月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
1月前
|
设计模式 算法 数据库连接
PHP中的设计模式:提高代码的可维护性和扩展性
【10月更文挑战第13天】 本文将探讨PHP中常见的设计模式及其在实际项目中的应用。通过对比传统编程方式,我们将展示设计模式如何有效地提高代码的可维护性和扩展性。无论是单例模式确保类的单一实例,还是观察者模式实现对象间的松耦合,每一种设计模式都为开发者提供了解决特定问题的最佳实践。阅读本文后,读者将能更好地理解和应用这些设计模式,从而提升PHP编程的效率和质量。
|
1月前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP开发领域,设计模式是解决常见问题的高效方案集合。它们不是具体的代码,而是一种编码和设计经验的总结。单例模式作为设计模式中的一种,确保了一个类仅有一个实例,并提供一个全局访问点。本文将深入探讨单例模式的基本概念、实现方式及其在PHP中的应用。
单例模式在PHP中的应用广泛,尤其在处理数据库连接、日志记录等场景时,能显著提高资源利用率和执行效率。本文从单例模式的定义出发,详细解释了其在PHP中的不同实现方法,并探讨了使用单例模式的优势与注意事项。通过对示例代码的分析,读者将能够理解如何在PHP项目中有效应用单例模式。
|
2月前
|
设计模式 算法 数据库连接
PHP中的设计模式:提高代码的可维护性与扩展性
设计模式在PHP开发中至关重要,如单例模式确保类仅有一个实例并提供全局访问点,适用于管理数据库连接或日志记录。工厂模式封装对象创建过程,降低系统耦合度;策略模式定义算法系列并使其可互换,便于实现不同算法间的切换。合理选择设计模式需基于需求分析,考虑系统架构,并通过测试驱动开发验证有效性,确保团队协作一致性和代码持续优化。设计模式能显著提升代码质量,解决开发中的设计难题。
33 8
|
2月前
|
设计模式 算法 PHP
PHP中的设计模式:提升代码的灵活性与可维护性
在本文中,我们将深入探讨PHP编程语言中的一种重要概念——设计模式。设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。它代表了最佳的实践,被有经验的面向对象的软件开发人员所采用。本文将通过具体的实例,展示如何在PHP项目中应用设计模式,以提高代码的灵活性和可维护性。无论你是PHP初学者还是经验丰富的开发者,都能从中获得有价值的见解。
|
2月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入探索与实践在软件开发的广袤天地中,PHP以其独特的魅力和强大的功能,成为无数开发者手中的得力工具。而在这条充满挑战与机遇的征途上,设计模式犹如一盏明灯,指引着我们穿越代码的迷雾,编写出更加高效、灵活且易于维护的程序。今天,就让我们聚焦于设计模式中的璀璨明珠——策略模式,深入探讨其在PHP中的实现方法及其实际应用价值。
策略模式,这一设计模式的核心在于它为软件设计带来了一种全新的视角和方法。它允许我们在运行时根据不同情况选择最适合的解决方案,从而极大地提高了程序的灵活性和可扩展性。在PHP这门广泛应用的编程语言中,策略模式同样大放异彩,为开发者们提供了丰富的创作空间。本文将从策略模式的基本概念入手,逐步深入到PHP中的实现细节,并通过一个具体的实例来展示其在实际项目中的应用效果。我们还将探讨策略模式的优势以及在实际应用中可能遇到的挑战和解决方案,为PHP开发者提供一份宝贵的参考。
|
2月前
|
设计模式 存储 数据库连接
探索PHP中的设计模式:提高代码的可维护性与扩展性
本文将深入探讨PHP中常用的设计模式,包括单例模式、工厂模式和观察者模式。通过具体的代码示例,展示如何在实际项目中应用这些设计模式,以提高代码的可维护性与扩展性。无论你是PHP初学者还是有一定经验的开发者,都可以通过本文的学习,提升你的编程技巧和项目架构能力。
|
2月前
|
设计模式 算法 PHP
PHP中的设计模式:提升代码的可维护性与扩展性
在软件开发中,设计模式是一套经过验证的解决特定问题的模板。对于使用PHP语言的开发者来说,合理运用设计模式不仅可以优化代码结构,还能显著提高项目的可维护性和扩展性。本文将探讨几种常见的设计模式及其在PHP中的应用,帮助开发者编写更高效、更灵活的代码。
36 2
|
2月前
|
设计模式 算法 搜索推荐
PHP中的设计模式:提高代码可维护性的秘诀
在本文中,我们将探讨PHP设计模式的重要性以及它们如何帮助开发者编写出更加灵活、可维护的代码。我们将介绍几种常见的设计模式,包括单例模式、工厂模式和策略模式,并通过实际示例展示它们在PHP中的应用。最后,我们会讨论何时使用这些设计模式以及在实际项目开发中的最佳实践。
37 1
|
2月前
|
设计模式 Java
Java设计模式-原型模式(3)
Java设计模式-原型模式(3)
Java设计模式-原型模式(3)