Java设计模式(工厂模式>抽象工厂模式和原型模式)

1.工厂模式

1.1 简单工厂模式

(1)基本介绍

a.简单工厂模式是属于创建模式,是工厂模式的一种,简单工厂模式
	是由一个工厂对象创建出哪一种产品类的实例。简单工厂模式是工
	厂模式家族里最简单使用的模式

b.定义了一个创建对象的类,有这个类封装实例化对象的行为

c.在软件开发中。当我们会用到大量的创建某类,或者某批对
	象时,就会使用到工厂模式

(2)代码展示

1.先定义一个抽象类,将不同的点设置为抽象方法

package com.pattern.设计模式.工厂模式和抽象工厂模式.简单工厂模式;

public abstract class Car {

    private String name;

    // 因为车的品牌不一样,所以设置为抽象方法
    public abstract void log();

    public void tyre(){
        System.out.println(name + "的轮胎");
    }

    public void frame(){
        System.out.println(name + "的车架");
    }

    public void engine(){
        System.out.println(name + "的引擎");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Car{" +
                "name='" + name + '\'' +
                '}';
    }
}

2.继承该抽象方法去重写其抽象方法(可以多创建一些车品牌)

package com.pattern.设计模式.工厂模式和抽象工厂模式.简单工厂模式;

public class AudiCar extends Car{
    @Override
    public void log() {
        System.out.println("奥迪");
    }
}

3.制作什么品牌的车自己输入

package com.pattern.设计模式.工厂模式和抽象工厂模式.简单工厂模式;

import java.util.Scanner;

public class MakeCar {

    private CarFactory factory;
    private Car car;

    public MakeCar(CarFactory factory){
        this.factory = factory;
    }

    public void makeCar(){
        String log = "";

        do {
            log = getLog();
            car = this.factory.createCar(log);

            if (car != null){
                car.log();
                car.tyre();
                car.frame();
                car.engine();
            } else {
                System.out.println("输入有误!没有该品牌的车型!!!");
                break;
            }
        } while (true);
    }

    public String getLog() {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要制作的品牌:");
        String log = scanner.next();
        return log;
    }
}

4.创建工厂类

package com.pattern.设计模式.工厂模式和抽象工厂模式.简单工厂模式;

public class CarFactory {

    public Car createCar(String log){
        Car car = null;

        if ("宝马".equals(log)){
            car = new BmwCar();
            car.setName("宝马");
        }else  if ("奔驰".equals(log)){
            car = new BenzCar();
            car.setName("奔驰");
        }else if ("奥迪".equals(log)){
            car = new AudiCar();
            car.setName("奥迪");
        }

        return car;
    }
}

5.测试类

package com.pattern.设计模式.工厂模式和抽象工厂模式.简单工厂模式;

public class Test {
    public static void main(String[] args) {
        CarFactory factory = new CarFactory();
        MakeCar makeCar = new MakeCar(factory);
        makeCar.makeCar();
    }
}

1.2 工厂方法模式

(1)基本介绍

a.工厂方法模式:定义一个创建对象的抽象方法,由子类决定要
	实例化的类,工厂方法模式将对象的实例化推迟到子类。

(2)代码展示
1.跟简单工厂模式一样

package com.pattern.设计模式.工厂模式和抽象工厂模式.工厂方法模式;

public abstract class Car {

    private String name;

    public abstract void getCar();

    public void tyre(){
        System.out.println(name + "的轮胎");
    }

    public void frame(){
        System.out.println(name + "的车架");
    }

    public void engine(){
        System.out.println(name + "的引擎");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Car{" +
                "name='" + name + '\'' +
                '}';
    }
}

2.跟简单工厂模式一样,可增加

package com.pattern.设计模式.工厂模式和抽象工厂模式.工厂方法模式;

public class ChinaBenzCar extends Car{
    @Override
    public void getCar() {
        setName("中国的奔驰汽车");
        System.out.println("中国的奔驰汽车 准备制作");
    }
}

3.跟简单工厂模式一样,可增加

package com.pattern.设计模式.工厂模式和抽象工厂模式.工厂方法模式;

public class USABenzCar extends Car{
    @Override
    public void getCar() {
        setName("美国的奔驰汽车");
        System.out.println("美国的奔驰汽车 准备制作");
    }
}

4.制作

package com.pattern.设计模式.工厂模式和抽象工厂模式.工厂方法模式;

import java.util.Scanner;

public abstract class MakeCar {

    // 定义一个抽象方法,让各个工厂子类自己去实现
    abstract Car createCar(String log);

    // 构造器
    public MakeCar(){
        Car car = null;
        String log;  // 制作的车品牌
        do {
            log = getLog();
            car = createCar(log);
            if (car != null){
                car.getCar();
                car.tyre();
                car.frame();
                car.engine();
            }else {
                System.out.println("你输入的品牌不对");
                break;
            }


        } while (true);
    }


    public String getLog(){
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要制作的品牌汽车:");
        String log = scanner.next();
        return log;
    }
}

5.测试

package com.pattern.设计模式.工厂模式和抽象工厂模式.工厂方法模式;

public class Test {
    public static void main(String[] args) {
        // 创建中国的车
//        new ChinaMakeCar();
        // 创建美国的汽车

        new USAMakeCar();

    }
}

2.抽象工厂模式

(1)基本介绍

a.抽象工厂模式:定义了一个interface用于创建相关或有依赖关系
	的对象簇,而无需知名具体的类。

b.抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合

c.抽象工厂模式就是对简单工厂模式的改进

d.将工厂抽象成两层,absfactory(抽象工厂)和具体实现的工厂
	子类,程序员可以根据创建对象类型使用对应的工厂子类,这
	样将单个的简单工厂类变成了工厂簇。更利于代码的维护和扩展。

(2)代码展示
1.还是Car类

package com.pattern.设计模式.工厂模式和抽象工厂模式.抽象工厂模式;

public abstract class Car {

    private String name;

    public abstract void getCar();

    public void tyre(){
        System.out.println(name + "的轮胎");
    }

    public void frame(){
        System.out.println(name + "的车架");
    }

    public void engine(){
        System.out.println(name + "的引擎");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Car{" +
                "name='" + name + '\'' +
                '}';
    }
}

2.中国奔驰类(可增加)

package com.pattern.设计模式.工厂模式和抽象工厂模式.抽象工厂模式;

public class ChinaBenzCar extends Car{
    @Override
    public void getCar() {
        setName("China");
        System.out.println("中国的奔驰汽车》》开始制作");
    }
}

3.mg的类

package com.pattern.设计模式.工厂模式和抽象工厂模式.抽象工厂模式;

public class USABenzCar extends Car{
    @Override
    public void getCar() {
        setName("USA");
        System.out.println("美国的奔驰汽车》》开始制作");
    }
}

4.创建一个抽象工厂

package com.pattern.设计模式.工厂模式和抽象工厂模式.抽象工厂模式;

public interface AbsFactory {

    public Car createCar(String log);
}

5.制作

package com.pattern.设计模式.工厂模式和抽象工厂模式.抽象工厂模式;

import java.util.Scanner;

public class MakeCar {

    AbsFactory absFactory;

    public MakeCar(AbsFactory absFactory){
        setAbsFactory(absFactory);
    }

    private void setAbsFactory(AbsFactory absFactory){
        Car car = null;
        String log = "";
        this.absFactory = absFactory;

        do {
            log = getLog();
            car = absFactory.createCar(log);
            if (car != null){
                car.getCar();
                car.tyre();
                car.frame();
                car.engine();
            }else {
                System.out.println("输入有误:");
                break;
            }
        }while (true);
    }

    public String getLog(){
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入:");
        String log = scanner.next();
        return log;
    }
}

6.测试

package com.pattern.设计模式.工厂模式和抽象工厂模式.抽象工厂模式;

public class Test {
    public static void main(String[] args) {
        new MakeCar(new ChinaMakeCar());
    }
}

3.总结

(1)工厂模式的意义

a.将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展的维护性

(2) 根据的是设计模式的依赖抽象原则

a.创建对象实例时,不要直接new类,而是把这个new类的动作放
	在一个工厂的方法中,并返回,有的书上说,变量不要直接持
	有具体类的引用

b.不要让类继承具体类,而是继承抽象类或者是实现接口

c.不要覆盖基类中已经实现的方法

PS:JDK在Calendar类中的getInstance,使用了简单工厂模式

4.原型模式

4.1 原型模式

(1) 基本介绍

①原型模式(Prototype):用原型实例指定创建对象的种类,并且通过
	拷贝这些原型,创建新的对象

②原型模式是一种创建型设计模式,允许一个对象可以再创建另外一
	个可定制的对象,无需知道如何创建的细节

③工作原理:通过将一个原型对象传给那个要发动创建的对象,这个
	要发动的对象通过请求原型对象拷贝它们自己来实现创建,即
	对象。Clone()

④在Spring中原型模式bean的创建就用到了原型模式

4.2 浅拷贝

(1) 浅拷贝的介绍

①对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值
	传递,也就是将该属性值赋值一份新的对象

②对于数据是引用数据类型的成员变量。那么浅拷贝会进行引用传
	递。也就是将该成员变量的引用值赋值给新的对象,因为实际上
	两个对象的成员变量都指向同一个实例,在这中情况下,在一个
	对象中修改该成员变量的值,会影响到另一个对象的成员变量的值

③浅拷贝是使用默认的clone()方法来实现拷贝的.

(2)代码展示
1.重写clone()是关键

package com.pattern.设计模式.原型模式.浅拷贝;

public class Car implements Cloneable{

    private String name;
    private Integer id;
    private String colour;

    public Car() {
    }

    public Car(String name, Integer id, String colour) {
        this.name = name;
        this.id = id;
        this.colour = colour;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getColour() {
        return colour;
    }

    public void setColour(String colour) {
        this.colour = colour;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Car{" +
                "name='" + name + '\'' +
                ", id=" + id +
                ", colour='" + colour + '\'' +
                '}';
    }

// 重写clone()方法
    @Override
    protected Object clone() throws CloneNotSupportedException {

        Car car = null;
        car = (Car) super.clone();
        return car;
    }
}

2.测试类

package com.pattern.设计模式.原型模式.浅拷贝;

import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Car car = new Car("宝马", 12138, "红色");
        System.out.println(car);
        Car car1 = (Car) car.clone();
        Car car2 = (Car) car.clone();
        Car car3 = (Car) car.clone();
        Car car4 = (Car) car.clone();

        System.out.println(car1);
        System.out.println(car == car1);
        List<Car> list = new ArrayList<>();
        list.add(car1);
        list.add(car2);
        list.add(car3);
        list.add(car4);
        System.out.println(list);

    }
}

4.3 深拷贝

(1) 深拷贝的介绍

①赋值对象的所有基本数据类型的成员变量值

②为所有引用数据类型的成员变量申请储存空间,并复制每个引用
	数据类型成员变量所引用的对象,直到该对象可达的所有对象,
	也就是说,对象深拷贝要对整个对象进行拷贝

③深拷贝实现方法1:重写clone()方法

④深拷贝实现方法2:通过对象序列化

(2)代码展示
1.Tyre类

package com.pattern.设计模式.原型模式.深拷贝;

import java.io.Serializable;

public class Tyre implements Serializable, Cloneable {

    private static final Long serialVersionUID = 1L;

    private String name;

    public Tyre() {
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Tyre{" +
                "name='" + name + '\'' +
                '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

2.Car类

package com.pattern.设计模式.原型模式.深拷贝;

import java.io.*;

public class Car implements Serializable, Cloneable {

    private static final Long serialVersionUID = 1L;
    private String log;
    private Tyre tyre;

    public Car() {
    }

    public Car(String log, Tyre tyre) {
        this.log = log;
        this.tyre = tyre;
    }

    public String getLog() {
        return log;
    }

    public void setLog(String log) {
        this.log = log;
    }

    public Tyre getTyre() {
        return tyre;
    }

    public void setTyre(Tyre tyre) {
        this.tyre = tyre;
    }

    @Override
    public String toString() {
        return "Car{" +
                "log='" + log + '\'' +
                ", tyre=" + tyre +
                '}';
    }

    // 方式1 深拷贝 重写clone()方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        // 基本数据类型直接clone
        Object d = null;
        d = super.clone();
        // 对引用数据类型单独拿出来clone
        Car car = (Car) d;
        car.tyre = (Tyre) tyre.clone();
        return car;
    }

    // 方式2 深拷贝 通过对象的序列化实现
    public Object getClone() throws IOException, ClassNotFoundException {
        // 创建流对象
        ByteArrayOutputStream byteArrayOutputStream = null;
        ObjectOutputStream objectOutputStream = null;
        ByteArrayInputStream byteArrayInputStream = null;
        ObjectInputStream objectInputStream = null;

        // 序列化
        byteArrayOutputStream = new ByteArrayOutputStream();
        objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(this); // 当前对象以对象流的方式输出

        // 反序列化
        byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        objectInputStream = new ObjectInputStream(byteArrayInputStream);
        Car car = (Car) objectInputStream.readObject();
        return car;

    }

}

3.测试类

package com.pattern.设计模式.原型模式.深拷贝;

import java.io.IOException;

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
        Car car = new Car();
        car.setLog("奔驰");
        car.setTyre(new Tyre("轮胎"));

        // 方式1 深拷贝
//        Car car1 = (Car) car.clone();
//        System.out.println(car);
//        System.out.println(car1);
//        System.out.println(car.hashCode());
//        System.out.println(car1.hashCode());

        // 方式2 深拷贝
        Car car2 = (Car) car.getClone();
        System.out.println(car);
        System.out.println(car2);
        System.out.println(car.hashCode());
        System.out.println(car2.hashCode());
    }
}

5.建造者模式

建造者模式 等等

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值