设计模式之创建型模式
简单工厂模式
//抽象产品类
package com.std.www.designPattern.simpleFactory;
public interface Phone {
void getWLAN();
void showElectricity();
void showBrand();
void start();
void close();
}
//具体产品A
package com.std.www.designPattern.simpleFactory;
public class PhoneA implements Phone{
@Override
public void getWLAN() {
System.out.println("手机A获取WLAN");
}
@Override
public void showElectricity() {
System.out.println("手机A查看电量");
}
@Override
public void showBrand() {
System.out.println("手机A的品牌为华为");
}
@Override
public void start() {
System.out.println("手机A开机");
}
@Override
public void close() {
System.out.println("手机A关机");
}
}
//具体产品B
package com.std.www.designPattern.simpleFactory;
public class PhoneB implements Phone{
@Override
public void getWLAN() {
System.out.println("手机B获取WLAN");
}
@Override
public void showElectricity() {
System.out.println("手机B查看电量");
}
@Override
public void showBrand() {
System.out.println("手机B的品牌为小米");
}
@Override
public void start() {
System.out.println("手机B开机");
}
@Override
public void close() {
System.out.println("手机B关机");
}
}
//简单工厂
package com.std.www.designPattern.simpleFactory;
public class PhoneFactory {
public Phone getPhone(String arg){
if(arg.equals("A")){
return new PhoneA();
}
else if(arg.equals("B")){
return new PhoneB();
}
else {
System.out.println("产品"+arg+"还未发布");
return null;
}
}
}
//客户端
package com.std.www.designPattern.simpleFactory;
public class Client {
public static void main(String[] args) {
PhoneFactory factory=new PhoneFactory();
Phone A=factory.getPhone("A");
Phone B=factory.getPhone("B");
Phone C=factory.getPhone("C");
A.start();
A.getWLAN();
A.showBrand();
A.showElectricity();
A.close();
B.start();
B.getWLAN();
B.showBrand();
B.showElectricity();
B.close();
}
}

简单工厂模式一般有一个产品工厂和生产具体产品的方法,一个抽象产品类,多个具体产品类,工厂根据传入的参数来创建对应的产品,这样的坏处为每当增加一个新的产品,必须改动生产产品的源代码,不符合开闭原则
简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,它允许创建对象而不必直接指定其具体类。以下是简单工厂模式的特点:
特点:
-
封装实例化过程: 简单工厂模式将对象的实例化过程封装在一个工厂类中,客户端不需要直接负责对象的创建过程。
-
提供统一接口: 工厂类提供一个方法(通常是静态方法),根据客户端的请求返回相应的具体对象实例,从而隐藏了对象的创建细节。
-
灵活性: 通过工厂方法来实例化对象,使得系统更容易扩展和修改。只需修改工厂方法中的实例化过程,而不必改变客户端代码。
-
降低耦合: 客户端只需要与工厂类交互,不需要与具体的产品类直接交互,降低了系统中各个类之间的耦合度。
-
代码重用: 可以在多个地方使用同一个工厂方法来获取相同类型的对象,提高代码的重用性。
优点:
- 对象创建集中管理: 通过工厂方法集中管理对象的创建,便于维护和管理。
- 隐藏细节: 将对象创建细节隐藏在工厂类中,对客户端屏蔽了对象的具体实现细节。
缺点:
- 不符合开闭原则: 新增产品类型时,需要修改工厂类,违反了开闭原则。
- 工厂类职责过重: 随着产品类型增多,工厂类会变得庞大而复杂。
适用场景:
- 当需要根据条件来创建某个特定类的实例时。
- 当希望封装创建对象的逻辑,使得客户端代码更简洁。
工厂方法模式
//Phone
package com.std.www.designPattern.factoryMethod;
public interface Phone {
void getWLAN();
void showElectricity();
void showBrand();
void start();
void close();
}
//PhoneA
package com.std.www.designPattern.factoryMethod;
public class PhoneA implements Phone {
@Override
public void getWLAN() {
System.out.println("手机A获取WLAN");
}
@Override
public void showElectricity() {
System.out.println("手机A查看电量");
}
@Override
public void showBrand() {
System.out.println("手机A的品牌为华为");
}
@Override
public void start() {
System.out.println("手机A开机");
}
@Override
public void close() {
System.out.println("手机A关机");
}
}
//PhoneB
package com.std.www.designPattern.factoryMethod;
public class PhoneB implements Phone {
@Override
public void getWLAN() {
System.out.println("手机B获取WLAN");
}
@Override
public void showElectricity() {
System.out.println("手机B查看电量");
}
@Override
public void showBrand() {
System.out.println("手机B的品牌为小米");
}
@Override
public void start() {
System.out.println("手机B开机");
}
@Override
public void close() {
System.out.println("手机B关机");
}
}
//PhoneFactory
package com.std.www.designPattern.factoryMethod;
import com.std.www.designPattern.factoryMethod.Phone;
public interface PhoneFactory {
Phone getPhone();
}
//PhoneAFactory
package com.std.www.designPattern.factoryMethod;
import com.std.www.designPattern.factoryMethod.Phone;
import com.std.www.designPattern.factoryMethod.PhoneA;
public class PhoneAFactory implements PhoneFactory{
@Override
public Phone getPhone() {
return new PhoneA();
}
}
//PhoneBFactory
package com.std.www.designPattern.factoryMethod;
import com.std.www.designPattern.factoryMethod.Phone;
import com.std.www.designPattern.factoryMethod.PhoneB;
public class PhoneBFactory implements PhoneFactory{
@Override
public Phone getPhone() {return new PhoneB();}
}
//Client
package com.std.www.designPattern.factoryMethod;
public class Client {
public static void main(String[] args) {
PhoneFactory factory=null;
factory=new PhoneAFactory();
Phone A = factory.getPhone();
factory=new PhoneBFactory();
Phone B=factory.getPhone();
A.start();
A.getWLAN();
A.showBrand();
A.showElectricity();
A.close();
B.start();
B.getWLAN();
B.showBrand();
B.showElectricity();
B.close();
}
}

相比于简答工厂模式,工厂方法模式多了一个抽象工厂接口,对于每一个产品,我就创建对应的产品工厂类,这样就符合开闭原则,对于新增的产品只需创建对应的工厂即可,但是这样会增加代码的冗余,每个产品类都要有一个具体的工厂类
工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它定义了一个创建对象的接口,但允许子类决定实例化哪个类。这种模式将对象的实例化延迟到子类中,使一个类的实例化过程可以通过其子类来完成。
特点:
-
定义创建对象的接口: 工厂方法模式定义一个创建对象的接口,但将对象的实际创建推迟到子类中。
-
创建过程延迟到子类: 具体的产品类由具体的工厂子类决定实例化,从而让子类决定创建对象的类型。
-
提供抽象工厂类: 工厂方法模式通常包括一个抽象工厂类,其中包含创建对象的抽象方法,由子类来实现。
-
解耦: 通过工厂方法,客户端代码与具体产品的实例化过程解耦,只依赖于抽象工厂接口。
优点:
- 降低耦合度: 将产品的实例化延迟到子类,降低了客户端代码与具体产品之间的依赖关系。
- 易于扩展: 可以轻松添加新的产品类和对应的工厂类,而不需要修改现有代码。
- 符合开闭原则: 符合开闭原则,可以在不修改已有代码的情况下扩展系统功能。
缺点:
- 增加类的数量: 每个具体产品都需要对应一个具体工厂类,导致类的数量增加。
适用场景:
- 当一个类不知道它所需要创建的对象的类时。
- 当一个类希望由其子类来指定所创建对象的具体类型时。
抽象工厂模式
//Phone
package com.std.www.designPattern.abstractFactory;
public interface Phone {
void getWLAN();
void showElectricity();
void showBrand();
void start();
void close();
}
//PhoneA
package com.std.www.designPattern.abstractFactory;
import com.std.www.designPattern.abstractFactory.Phone;
public class PhoneA implements Phone {
@Override
public void getWLAN() {
System.out.println("手机A获取WLAN");
}
@Override
public void showElectricity() {
System.out.println("手机A查看电量");
}
@Override
public void showBrand() {
System.out.println("手机A的品牌为华为");
}
@Override
public void start() {
System.out.println("手机A开机");
}
@Override
public void close() {
System.out.println("手机A关机");
}
}
//PhoneB
package com.std.www.designPattern.abstractFactory;
import com.std.www.designPattern.abstractFactory.Phone;
public class PhoneB implements Phone {
@Override
public void getWLAN() {
System.out.println("手机B获取WLAN");
}
@Override
public void showElectricity() {
System.out.println("手机B查看电量");
}
@Override
public void showBrand() {
System.out.println("手机B的品牌为小米");
}
@Override
public void start() {
System.out.println("手机B开机");
}
@Override
public void close() {
System.out.println("手机B关机");
}
}
//Earphone
package com.std.www.designPattern.abstractFactory;
public interface Earphone {
void getWLAN();
void showElectricity();
void showBrand();
void start();
void close();
}
//EarphoneA
package com.std.www.designPattern.abstractFactory;
public class EarphoneA implements Earphone{
@Override
public void getWLAN() {
System.out.println("耳机A获取WLAN");
}
@Override
public void showElectricity() {
System.out.println("耳机A查看电量");
}
@Override
public void showBrand() {
System.out.println("耳机A的品牌为华为");
}
@Override
public void start() {
System.out.println("耳机A开机");
}
@Override
public void close() {
System.out.println("耳机A关机");
}
}
//EarphoneB
package com.std.www.designPattern.abstractFactory;
public class EarphoneB implements Earphone{
@Override
public void getWLAN() {
System.out.println("耳机B获取WLAN");
}
@Override
public void showElectricity() {
System.out.println("耳机B查看电量");
}
@Override
public void showBrand() {
System.out.println("耳机B的品牌为小米");
}
@Override
public void start() {
System.out.println("耳机B开机");
}
@Override
public void close() {
System.out.println("耳机B关机");
}
}
//ProductFactory
package com.std.www.designPattern.abstractFactory;
import com.std.www.designPattern.abstractFactory.Phone;
public interface ProductFactory {
Phone getPhone();
Earphone getEarphone();
}
//HuaiWeiFactory
package com.std.www.designPattern.abstractFactory;
import com.std.www.designPattern.abstractFactory.Phone;
import com.std.www.designPattern.abstractFactory.PhoneA;
public class HuaiWeiFactory implements ProductFactory{
@Override
public Phone getPhone() {
return new PhoneA();
}
@Override
public Earphone getEarphone() {
return new EarphoneA();
}
}
//XiaoMiFactory
package com.std.www.designPattern.abstractFactory;
import com.std.www.designPattern.abstractFactory.Phone;
import com.std.www.designPattern.abstractFactory.PhoneB;
public class XiaoMiFactory implements ProductFactory{
@Override
public Phone getPhone() {
return new PhoneB();
}
@Override
public Earphone getEarphone() {
return new EarphoneB();
}
}
//Client
package com.std.www.designPattern.abstractFactory;
import com.std.www.designPattern.abstractFactory.Phone;
public class Client {
public static void main(String[] args) {
ProductFactory productFactory=null;
Phone phone=null;
Earphone earphone=null;
//生产华为产品族的产品
productFactory=new HuaiWeiFactory();
phone=productFactory.getPhone();
earphone=productFactory.getEarphone();
phone.start();
earphone.start();
phone.showBrand();
earphone.showBrand();
phone.close();
earphone.close();
//生产小米产品族的产品
productFactory=new XiaoMiFactory();
phone=productFactory.getPhone();
earphone=productFactory.getEarphone();
phone.start();
earphone.start();
phone.showBrand();
earphone.showBrand();
phone.close();
earphone.close();
}
}

抽象工厂模式一般含有一个超级工厂接口,多个不同的产品接口,一般这些产品接口属于同一个产品族,而不同产品族之间相同种类的产品为同一个产品结构,横向为产品族,纵向为产品等级
超级工厂定义了一个产品族中所有的产品的类型,对于不同的产品族只需创建不同的工厂即可,例如华为产品族创建华为工厂即可,该模式适合产品族中产品固定不会频繁变化的情况
例子中Phone和Earphone属于同一个产品族,而Phone和PhoneA和PhoneB属于同一个产品等级
抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。抽象工厂模式是工厂方法模式的延伸,它以一组工厂的方式提供对象的创建。
特点:
-
提供接口: 定义用于创建产品家族的接口,这些产品家族包含多个相互依赖或相关联的对象。
-
抽象工厂: 包括一个或多个抽象工厂类,每个抽象工厂类都可以创建一整套产品(一族产品)。
-
多个具体工厂: 每个具体工厂对应于一个具体的产品族,实现了创建产品家族的具体方法。
-
创建相关对象: 抽象工厂提供了创建相关或依赖对象的一种方式,确保这些相关的对象能够一起使用。
优点:
- 封装家族产品创建过程: 抽象工厂模式封装了产品族的创建过程,使得客户端不需要了解具体产品的创建细节。
- 易于替换产品族: 由于使用了抽象工厂,可以轻松切换不同的产品族,而不需要修改客户端代码。
- 符合开闭原则: 在不修改现有代码的情况下,可以引入新的产品族。
缺点:
- 增加新产品族困难: 添加新的产品族会涉及修改抽象工厂接口和所有具体工厂的实现,这可能增加系统的复杂性。
适用场景:
- 当希望一次性创建一整套相关或依赖对象时。
- 当系统需要从多个产品族中选择一种。
建造者模式
//Builder
package com.std.www.designPattern.builder;
public interface Builder {
void buildWheel();
void buildChair();
void buildRoof();
Car getCar();
}
//CarBuilderA
package com.std.www.designPattern.builder;
public class CarBuilderA implements Builder{
private final Car car;
public CarBuilderA() {
car=new Car();
}
@Override
public void buildWheel() {
car.setWheel("白色轮胎");
System.out.println(car.getWheel());
}
@Override
public void buildChair() {
car.setChair("黑色座椅");
System.out.println(car.getChair());
}
@Override
public void buildRoof() {
car.setRoof("红色车顶");
System.out.println(car.getRoof());
}
@Override
public Car getCar() {
return car;
}
}
//CarBuilderB
package com.std.www.designPattern.builder;
public class CarBuilderB implements Builder{
private final Car car;
public CarBuilderB() {
car=new Car();
}
@Override
public void buildWheel() {
car.setWheel("绿色轮胎");
System.out.println(car.getWheel());
}
@Override
public void buildChair() {
car.setChair("黄色座椅");
System.out.println(car.getChair());
}
@Override
public void buildRoof() {
car.setRoof("紫色车顶");
System.out.println(car.getRoof());
}
@Override
public Car getCar() {
return car;
}
}
//Car
package com.std.www.designPattern.builder;
public class Car {
private String wheel;
private String chair;
private String roof;
@Override
public String toString() {
return "Car{" +
"wheel='" + wheel + '\'' +
", chair='" + chair + '\'' +
", roof='" + roof + '\'' +
'}';
}
public String getWheel() {
return wheel;
}
public void setWheel(String wheel) {
this.wheel = wheel;
}
public String getChair() {
return chair;
}
public void setChair(String chair) {
this.chair = chair;
}
public String getRoof() {
return roof;
}
public void setRoof(String roof) {
this.roof = roof;
}
}
//Director
package com.std.www.designPattern.builder;
public class Director {
public Car build(Builder builder){
builder.buildWheel();
builder.buildChair();
builder.buildRoof();
return builder.getCar();
}
}
//Client
package com.std.www.designPattern.builder;
public class Client {
public static void main(String[] args) {
Director director=new Director();
Car car=null;
car=director.build(new CarBuilderA());
System.out.println(car.toString());
car=director.build(new CarBuilderB());
System.out.println(car.toString());
}
}

建造者模式一般都有一个指挥类,一个复杂产品类,一个建造者接口,通过对接口不同的实现可以建造出不同的产品,虽然建造过程都一样,例如例子中同样的建造过程得到不同的车子
指挥类负责建造产品的顺序,具体建造类负责建造具体的产品
下面为无指挥者的建造者模式,将建造顺序交给客户,提高了的灵活性,并且具有默认值
//Builder
package com.std.www.designPattern.builder;
public interface Builder {
Builder buildWheel(String color);
Builder buildChair(String color);
Builder buildRoof(String color);
Car getCar();
}
//Car
package com.std.www.designPattern.builder;
public class Car {
private String wheel="无色轮胎";
private String chair="无色座椅";
private String roof="无色车顶";
@Override
public String toString() {
return "Car{" +
"wheel='" + wheel + '\'' +
", chair='" + chair + '\'' +
", roof='" + roof + '\'' +
'}';
}
public String getWheel() {
return wheel;
}
public void setWheel(String wheel) {
this.wheel = wheel;
}
public String getChair() {
return chair;
}
public void setChair(String chair) {
this.chair = chair;
}
public String getRoof() {
return roof;
}
public void setRoof(String roof) {
this.roof = roof;
}
}
//CarBuilder
package com.std.www.designPattern.builder;
public class CarBuilder implements Builder{
private final Car car;
public CarBuilder() {
car=new Car();
}
@Override
public Builder buildWheel(String color) {
car.setWheel(color);
System.out.println(car.getWheel());
return this;
}
@Override
public Builder buildChair(String color) {
car.setChair(color);
System.out.println(car.getChair());
return this;
}
@Override
public Builder buildRoof(String color) {
car.setRoof(color);
System.out.println(car.getRoof());
return this;
}
@Override
public Car getCar() {
return car;
}
}
//Client
package com.std.www.designPattern.builder;
public class Client {
public static void main(String[] args) {
Builder builder=new CarBuilder();
//链式编程
builder.buildRoof("红色")
.buildWheel("蓝色");
Car car=builder.getCar();
System.out.println(car.toString());
}
}

这里的建造顺序和建造具体信息交给客户端选择,并其含有默认产品也可以不去建造,建造者模式适合一类具有相似结构的产品,如果产品之间差异性很大则不适合该模式
建造者模式(Builder Pattern)是一种创建型设计模式,用于将复杂对象的构建过程与其表示分离,以便可以按步骤构建不同的表示形式。它允许您创建对象的不同组合,同时保持相同的构建过程。
主要角色:
-
产品(Product): 被构建的复杂对象。它包含需要构建的所有部分。
-
抽象建造者(Builder): 声明了创建产品各个部分的接口。
-
具体建造者(Concrete Builder): 实现了抽象建造者接口,负责具体产品部件的创建和装配。
-
指挥者(Director): 负责使用建造者模式,以正确的顺序构建产品。它与具体的建造者交互,指导构建过程。
特点:
-
构建步骤分离: 将一个复杂对象的构建过程分解为若干步骤,以便逐步构建产品。
-
创建不同表示: 允许建造者对象根据特定的需求,以不同的顺序或方式构建产品。
-
隐藏构建细节: 将构建的细节与产品的表示分离,使得用户无需了解产品内部的构建过程即可构建对象。
优点:
-
灵活性: 可以按照步骤或顺序创建不同的产品对象。
-
封装性: 将构建过程封装在单独的构建器中,使得构建过程更易于管理和修改。
缺点:
- 可能增加系统复杂性: 当产品较为简单时,引入建造者模式可能会增加系统的复杂度。
适用场景:
-
需要构建复杂对象,且对象的构建方式可以根据不同需求变化。
-
当一个对象有多个组成部分,且构建的步骤和顺序相对固定,但不同组合形式会产生不同的表示时。
原型模式
原型模式本质就是克隆一个相同的对象,分为浅克隆和深克隆
浅克隆
//Car
package com.std.www.designPattern.prototype;
import java.util.Date;
public class Car implements Cloneable{
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Car{" +
"Model='" + Model + '\'' +
", Brand='" + Brand + '\'' +
", Color='" + Color + '\'' +
", EngineType='" + EngineType + '\'' +
", date=" + date +
'}';
}
private String Model;
private String Brand;
private String Color;
private String EngineType;
private Date date;
public Car(String model, String brand, String color, String engineType, Date date) {
Model = model;
Brand = brand;
Color = color;
EngineType = engineType;
this.date = date;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getModel() {
return Model;
}
public void setModel(String model) {
Model = model;
}
public String getBrand() {
return Brand;
}
public void setBrand(String brand) {
Brand = brand;
}
public String getColor() {
return Color;
}
public void setColor(String color) {
Color = color;
}
public String getEngineType() {
return EngineType;
}
public void setEngineType(String engineType) {
EngineType = engineType;
}
}
//Client
package com.std.www.designPattern.prototype;
import java.util.Date;
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
Date date=new Date();
Car car=new Car("轿车","劳斯莱斯","红色","电动",date);
Car carClone= (Car) car.clone();
System.out.println(car.toString()+"\n"+car.hashCode());
System.out.println(carClone.toString()+"\n"+carClone.hashCode());
date.setTime(3600*60*24*120);
System.out.println(car.toString()+"\n"+car.hashCode());
System.out.println(carClone.toString()+"\n"+carClone.hashCode());
}
}

深克隆
//Car
package com.std.www.designPattern.prototype;
import java.util.Date;
public class Car implements Cloneable{
@Override
protected Object clone() throws CloneNotSupportedException {
Car car= (Car) super.clone();
car.setDate((Date) this.date.clone());
return car;
}
@Override
public String toString() {
return "Car{" +
"Model='" + Model + '\'' +
", Brand='" + Brand + '\'' +
", Color='" + Color + '\'' +
", EngineType='" + EngineType + '\'' +
", date=" + date +
'}';
}
private String Model;
private String Brand;
private String Color;
private String EngineType;
private Date date;
public Car(String model, String brand, String color, String engineType, Date date) {
Model = model;
Brand = brand;
Color = color;
EngineType = engineType;
this.date = date;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getModel() {
return Model;
}
public void setModel(String model) {
Model = model;
}
public String getBrand() {
return Brand;
}
public void setBrand(String brand) {
Brand = brand;
}
public String getColor() {
return Color;
}
public void setColor(String color) {
Color = color;
}
public String getEngineType() {
return EngineType;
}
public void setEngineType(String engineType) {
EngineType = engineType;
}
}
//Client
package com.std.www.designPattern.prototype;
import java.util.Date;
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
Date date=new Date();
Car car=new Car("轿车","劳斯莱斯","红色","电动",date);
Car carClone= (Car) car.clone();
System.out.println(car.toString()+"\n"+car.hashCode());
System.out.println(carClone.toString()+"\n"+carClone.hashCode());
date.setTime(3600*60*24*120);
System.out.println(car.toString()+"\n"+car.hashCode());
System.out.println(carClone.toString()+"\n"+carClone.hashCode());
}
}

通过两个例子可以看出,浅克隆对于克隆对象内部的引用字段并没有创建一个新的对象,而是让克隆后的指向原来的字段,所以字段改变则克隆和原型都会改变,而深克隆则直接新建立了一个对象字段,即把字段也克隆了一遍
原型模式(Prototype Pattern)是一种创建型设计模式,允许通过复制现有对象来创建新对象,而无需通过标准的构造方式来创建。它通过复制现有对象的实例来创建新对象,从而避免了复杂的构造过程。
主要角色:
-
原型接口(Prototype): 定义用于克隆自身的接口。
-
具体原型类(Concrete Prototype): 实现原型接口,实现克隆方法以复制自身。
-
客户端(Client): 使用原型对象来克隆新对象。
特点:
-
基于原型克隆: 原型模式基于克隆现有对象来创建新对象。
-
简化对象创建: 通过复制现有对象,避免了直接调用构造函数来创建新对象。
-
动态添加对象: 可以动态添加或删除对象。
优点:
-
简化对象创建: 避免了复杂的构造过程,使得创建新对象变得更加简单。
-
灵活性: 可以动态添加、删除对象,以及在运行时改变对象的状态。
缺点:
- 原型对象必须实现克隆方法: 如果原型对象无法实现克隆方法,那么无法使用原型模式。
适用场景:
-
对象创建成本高昂: 当对象的创建成本很高或者构造过程复杂时,原型模式能够提供一个更高效的解决方案。
-
动态对象创建: 当需要动态添加或删除对象,或者动态改变对象状态时,原型模式是一个合适的选择。
创建型模式就6个
单例模式,简单工厂模式,工厂方法模式,抽象工厂模式,建造者模式,原型模式

浙公网安备 33010602011771号