三、创建型模式的作用
3.2原型(Prototype)模式
每一个高可用的框架都是设计模式嵌套使用,而不是单个使用
本体给外部提供一个克隆进行使用,这时候本体就是原型 ,这种方式可以避免重复创建相同的对象,提高了性能和效率。
就比如从数据库查询数据,每次查询的数据都一样,这时候就多次查询的数据就很占用空间,我们一般可以用Redis进行缓存如果查询条件一样就从缓存读取。
原型模式的代码实现
1.建立 Dog 类 :提供了clone()方法
java
/**
* 当前对象是可克隆的
*/
public class Dog implements Cloneable {
private String dogName;
private Integer age;
public Dog() {
System.out.println("创建了Dog对象");
}
public String getDogName() {
return dogName;
}
public void setDogName(String dogName) {
this.dogName = dogName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"dogName='" + dogName + ''' +
", age=" + age +
'}';
}
//再创建一只狗,赋予所有属性
@Override
protected Object clone() throws CloneNotSupportedException {
Dog dog = new Dog();
dog.setDogName(dogName);
dog.setAge(age);
return dog;
}
}
2.建立DogData 类:(模拟从数据库拿数据)
java
public class DogData {
//缓存user.序列化和反序列化-深克隆
private Map<String, Dog> dogCache = new HashMap<>();
/**
* 从数据库查数据
* @return
*/
public Dog getUser(String username) throws Exception {
Dog dog = null;
//缓存中没有
if(!dogCache.containsKey(username)){
//查询数据库
dog = getUserFromDb(username);
}else {
//从缓存中直接拿,脏缓存问题
//原型已经拿到,但是不能直接给。(
dog = dogCache.get(username);
System.out.println("从缓存中拿到的是:"+ dog);
//从这个对象快速得到一个克隆体 == 原型模式
dog = (Dog) dog.clone();
}
return dog;
}
private Dog getUserFromDb(String username) throws Exception{
System.out.println("从数据库查到:"+username);
Dog dog = new Dog();
dog.setDogName(username);
dog.setAge(18);
//给缓存中放一个clone
dogCache.put(username, (Dog) dog.clone());
return dog;
}
}
3.建立DogTest类
Java
public class DogTest {
public static void main(String[] args) throws Exception {
DogData dogData = new DogData();
//得到的是克隆体
Dog 泰迪 = dogData.getUser("泰迪");
System.out.println("1==>"+泰迪);
泰迪.setDogName("泰迪副本");
System.out.println("泰迪自己改了:"+泰迪);
//得到的是克隆体
Dog 金毛 = dogData.getUser("泰迪");
System.out.println("2-->"+金毛);
//得到的是克隆体
Dog 柯基 = dogData.getUser("泰迪");
System.out.println("3-->"+柯基);
//得到的是克隆体
Dog 柴犬 = dogData.getUser("泰迪");
System.out.println("4-->"+柴犬);
System.out.println(泰迪 == 柯基);
}
}
以上代码就实现了原型模式
泰迪创建了克隆体并放入缓存当中,如果金毛等需要泰迪的数据就从缓存中拿,即使泰迪更改了名字,也不会影响,因为克隆体已存在在缓存当中,不再改变
3.3工厂(Factory)模式
工厂模式是一种用于管理对象创建的设计模式,可以提高代码的可扩展性和可维护性
1.简单工厂(Simple Factory )
简单工厂中有三个角色
- Factory:工厂角色, ChinaSimpleFactory
- Product:抽象产品角色,AbstractPhone
- ConcreteProduct:具体产品角色, HuaWeiPhone 、XiaoMiPhone
1.建立 AbstractPhone 类 (抽象类,定义了一个品牌变量和一个抽象方法)
java
public abstract class AbstractPhone {
String brand;
public abstract void make();
}
2.建立HuaWeiPhone 类:(继承抽象类,并实现其中的方法,生产华为手机)
Java
public class HuaWeiPhone extends AbstractPhone {
public HuaWeiPhone(){
this.brand = "华为手机";
}
@Override
public void make() {
System.out.println(brand +"--》数智世界 一触即达");
}
}
3.建立XiaoMiPhone 类:(继承抽象类,并实现其中的方法,生产小米手机)
Java
public class XiaoMiPhone extends AbstractPhone {
public XiaoMiPhone(){
this.brand = "小米手机";
}
@Override
public void make() {
System.out.println(brand +"--> 遥遥领先");
}
}
4.建立ChinaSimpleFactory 类:(一个简单的工厂,用来管理各个产品)
Java
public class ChinaSimpleFactory {
/**
*
* @param type Class: 好像具有扩展性,但是没有解决实际问题
* @return
*/
public AbstractPhone newCar(String type){
//核心方法:一切从简
if("HuaWei".equals(type)){
// 钣金、喷漆、放发动机、申请环保
return new HuaWeiPhone();
}else if("XiaoMi".equals(type)){
return new XiaoMiPhone();
}
//.....
return null;
}
}
5.建立MainTest测试
java
public class MainTest {
public static void main(String[] args) {
ChinaSimpleFactory factory = new ChinaSimpleFactory();
AbstractPhone huaWei = factory.newCar("HuaWei");
AbstractPhone xiaoMi = factory.newCar("XiaoMi");
huaWei.make();
xiaoMi.make();
}
}
简单工厂的缺点
如果有更多的品牌手机,在工厂中就需要添加更多的if else 代码,违反开闭原则。应该直接扩展出一个类来造
2.工厂方法(Factory Method)
工厂方法有四个角色
- Product:抽象产品 AbstractPhone
- ConcreteProduct:具体产品 HuaWeiPhone、XiaoMiPhone
- Factory:抽象工厂 AbstractPhoneFactory
- ConcreteFactory:具体工厂 HuaWeiPhoneFactory、XiaoMiPhoneFactory
1.建立AbstractPhone 类 (抽象类,定义了一个品牌变量和一个抽象方法)
Java
public abstract class AbstractPhone {
String brand;
public abstract void make();
}
2.建立HuaWeiPhone、XiaoMiPhone 类 (继承抽象类,并实现其中的方法,生产华为、小米手机)
Java
public class HuaWeiPhone extends AbstractPhone {
public HuaWeiPhone(){
this.brand = "华为手机";
}
@Override
public void make() {
System.out.println(brand +"数智世界 一触即达");
}
}
public class XiaoMiPhone extends AbstractPhone {
public XiaoMiPhone(){
this.brand = "小米手机";
}
@Override
public void make() {
System.out.println(brand +"--> 遥遥领先...");
}
}
3.建立AbstractPhoneFactory (一个手机的抽象类)
csharp
public abstract class AbstractPhoneFactory {
public abstract AbstractPhone newPhone();
//我能造口罩.....
}
4.建立HuaWeiPhoneFactory、XiaoMiPhoneFactory (华为、小米的工厂类)
Java
public class HuaWeiPhoneFactory extends AbstractPhoneFactory {
@Override
public AbstractPhone newPhone() {
return new HuaWeiPhone();
}
}
public class XiaoMiPhoneFactory extends AbstractPhoneFactory {
@Override
public AbstractPhone newPhone() {
return new XiaoMiPhone();
}
}
5.建立测试类MainTest
java
public class MainTest {
public static void main(String[] args) {
AbstractPhoneFactory phoneFactory = new XiaoMiPhoneFactory();
AbstractPhone abstractXiaoMiPhone = phoneFactory.newPhone();
abstractXiaoMiPhone.make();
phoneFactory = new HuaWeiPhoneFactory();
AbstractPhone abstractHuaWeiPhone = phoneFactory.newPhone();
abstractHuaWeiPhone.make();
}
}
工厂方法实现了面向接口编程,当然缺点就是:当系统复杂度增加时,工厂方法的品类过于单一,就比如华为和小米不仅要造手机,当要造汽车的时候就很难去优化了
3.抽象工厂(Abstract Factory)
提供了一个接口来创建一系列相关或相互依赖的对象,而无需指定它们具体的类。
它将具体产品的创建与使用分离,使得系统更加灵活和可扩展。当需要添加新的产品类型时,只需要实现新的具体工厂类,而不需要修改使用这些产品的其他部分。
1.建立AbstractCar 、AbstractPhone 抽象类 (定义了汽车名字,汽车制造方法,手机名字,手机自造方法)
Java
public abstract class AbstractCar {
String carName;
public abstract void run();
}
public abstract class AbstractPhone {
String brand;
public abstract void make();
}
2.建立HuaWeiCar、HuaWeiPhone、XiaoMiCar、XiaoMiPhone (实现制造手机和汽车)
Java
public class HuaWeiCar extends AbstractCar {
public HuaWeiCar(){
this.carName = "华为汽车";
}
@Override
public void run() {
System.out.println(carName +"数智世界 一触即达");
}
}
public class HuaWeiPhone extends AbstractPhone {
public HuaWeiPhone(){
brand = "华为";
}
@Override
public void make() {
System.out.println("数智世界 一触即达");
}
}
public class XiaoMiCar extends AbstractCar {
public XiaoMiCar(){
this.carName = "小米汽车";
}
@Override
public void run() {
System.out.println(carName +"遥遥领先");
}
}
public class XiaoMiPhone extends AbstractPhone {
public XiaoMiPhone(){
this.brand = "小米";
}
@Override
public void make() {
System.out.println("瑶瑶领先");
}
}
3.建立 ChinaFactory (定义了汽车、手机制造两个抽象方法)
java
public abstract class ChinaFactory {
abstract AbstractCar newCar();
abstract AbstractPhone newPhone();
}
4.建立ChinaPhoneFactory 、ChinaCarFactory (定义了汽车、手机制造中的一个方法)
Java
public abstract class ChinaCarFactory extends ChinaFactory {
@Override
abstract AbstractCar newCar();
@Override
AbstractPhone newPhone() {
return null;
}
}
public abstract class ChinaPhoneFactory extends ChinaFactory {
@Override
AbstractCar newCar() {
return null;
}
abstract AbstractPhone newPhone();
}
5.建立ChinaHuaWeiCarFactory、ChinaHuaWeiPhoneFactory、ChinaXiaoMiCarFactory、ChinaXiaoMiPhoneFactory (实现各种品牌的手机、汽车制造工厂)
Java
public class ChinaHuaWeiCarFactory extends ChinaCarFactory {
@Override
AbstractCar newCar() {
return new HuaWeiCar();
}
}
public class ChinaHuaWeiPhoneFactory extends ChinaPhoneFactory {
@Override
AbstractPhone newPhone() {
return new HuaWeiPhone();
}
}
public class ChinaXiaoMiCarFactory extends ChinaCarFactory {
@Override
AbstractCar newCar() {
return new XiaoMiCar();
}
}
public class ChinaXiaoMiPhoneFactory extends ChinaPhoneFactory {
@Override
AbstractPhone newPhone() {
return new XiaoMiPhone();
}
}
6.建立测试类MainTest
Java
public class MainTest {
public static void main(String[] args) {
//
ChinaFactory chinaFactory = new ChinaXiaoMiPhoneFactory();
AbstractPhone xiaoMiPhone = chinaFactory.newPhone();
xiaoMiPhone.make();
chinaFactory =new ChinaXiaoMiCarFactory();
AbstractCar xiaoMiCar = chinaFactory.newCar();
xiaoMiCar.run();
chinaFactory = new ChinaHuaWeiPhoneFactory();
AbstractPhone huaWeiPhone = chinaFactory.newPhone();
huaWeiPhone.make();
chinaFactory = new ChinaHuaWeiCarFactory();
AbstractCar huaWeiCar = chinaFactory.newCar();
huaWeiCar.run();
}
}
以上代码就实现了抽象工厂,虽然刚开始需要建立很多的抽象类,还有抽象工厂,但是后面扩展很方便,系统需要增强新的功能只需要建立相应的抽象、抽象工厂、实现类即可
3.4 建造者(Builder)模式
建造者模式中三个角色
- 产品角色(Product):Phone
- 抽象建造者(Builder):AbstractBuilder
- 具体建造者(Concrete Builder):XiaomiBuilder
1.建立 Phone 类 (定义了一个手机类包含了各种参数)
java
@Builder
@ToString
public class Phone {
protected String cpu;
protected String mem;
protected String disk;
protected String cam;
}
2.建立 AbstractBuilder 抽象类 (定义了制造手机参数方法的抽象类)
Java
public abstract class AbstractBuilder {
Phone phone;
abstract AbstractBuilder makeCpu(String cpu);
abstract AbstractBuilder makeMem(String mem);
abstract AbstractBuilder makeDisk(String disk);
abstract AbstractBuilder makeCam(String cam);
Phone getProduct(){
return phone;
}
}
3.建立XiaomiBuilder 类 (实现了抽象类中的方法)
typescript
public class XiaomiBuilder extends AbstractBuilder{
public XiaomiBuilder(){
phone = Phone.builder().build();
}
@Override
AbstractBuilder makeCpu(String cpu) {
phone.cpu = cpu;
return this;
}
@Override
AbstractBuilder makeMem(String mem) {
phone.mem = mem;
return this;
}
@Override
AbstractBuilder makeDisk(String disk) {
phone.disk = disk;
return this;
}
@Override
AbstractBuilder makeCam(String cam) {
phone.cam = cam;
return this;
}
}
4.建立测试类MainTest
java
public class MainTest {
public static void main(String[] args) {
AbstractBuilder builder = new XiaomiBuilder();
//链式建造者
Phone phone = builder.makeCpu("骁龙8个8")
.makeCam("2亿")
.makeDisk("1T")
.makeMem("16G")
.getProduct();
System.out.println(phone);
//lombok提供的建造模式
Phone build = Phone.builder()
.cpu("1亿")
.mem("2T")
.cam("3G")
.build();
System.out.println(build);
}
}