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());
}
}