常用创建型设计模式

建造者模式

当问题注重对象的创建过程,并且要求创建同类对象的不同产品时用建造者模式。例如房子的构建,地基->钢筋工程->堆砌砖瓦->粉刷,注重创建过程,但是对于平房和楼房来说,过程是一样的但是相应步骤的实现是不一样的。

建造者模式的基本构成
Product定义了产品的部件
Abstract Builder规定Worker行为
real Worker定义了各产品部件的构建方法,并且创建出实际的产品,并且可有多个Worker,可以有多个不同产品实现(平房与楼房)
Director则主要控制产品制作的流程,可有多个Director,有多个种不同的流程
在这里插入图片描述
这样便将产品的构建与表现分离

//产品
public class Product {
//  产品部件
    private String buildA;
    private String buildB;
    
    public String getBuildA() {
        return buildA;
    }
    public void setBuildA(String buildA) {
        this.buildA = buildA;
    }
    public String getBuildB() {
        return buildB;
    }
    public void setBuildB(String buildB) {
        this.buildB = buildB;
    }
}

//抽象工人
public abstract class Builder {
//    创建产品零件
    abstract void buildA();
    abstract void buildB();

//    完工得到产品
    abstract Product getProduct();
}

//工人
public class Worker extends Builder{
    private Product product;
    
    public Worker() {
        product = new Product();
    }
    @Override
    void buildA() {
        product.setBuildA("A部件完成");
    }
    @Override
    void buildB() {
        product.setBuildB("B部件完成");
    }
    @Override
    Product getProduct() {
        return product;
    }
}

//指挥工创建
public class Director {

    //将产品交给抽象的builder,对于不同的Worker就有不同的实现
    public Product build(Builder builder){
        //控制builder的建造顺序
        builder.buildA();
        builder.buildB();

       //返回产品
        return builder.getProduct();
    }
    
//测试
    public static void main(String[] args) {
        Director director=new Director();
        Product product=director.build(new Worker());
    }
}

链式编程取代director

//抽象工人
public abstract class Builder {
//    创建产品零件
    abstract Builder buildA();
    abstract Builder buildB();

//    完工得到产品
    abstract Product getProduct();
}

public class Test{
    public static void main(String[] args) {
        //构建顺序可由我们自己控制
        Product product=new Worker().buildA().buildB().getProduct();
    }
}

工厂模式

我们假设有Car接口规定汽车的基本信息,类Tesla和Ferrari是Car的两种实现,顾客Consumer得到汽车的实例。
在这里插入图片描述

public class Consumer {
    public static void main(String[] args) {
        car car1=new Tesla();
        car car2=new Ferrari();
    }
}

若按照非工厂模式我们的得到实例需使用new,有两个问题:一是用new创建的话需要了解所有的接口(可能带有大量参数)和实现类;二是直接使用new相当于顾客创造汽车,意义不符。

静态工厂模式
现在加入第三方工厂,可以代替客户制造汽车,那么客户直接从CarFactory直接拿到车。
在这里插入图片描述

public class Consumer {
    public static void main(String[] args) {
        Car car1 = Carfactory.getCar("Ferrari");
        Car car2 = Carfactory.getCar("Tesla");
    }
}

public class Carfactory {
//    方法1
    public static Car getCar(String carname){
        if(carname.equals("Ferrari")){
            return new Ferrari();
        }
        else if(carname.equals("Tesla")){
            return new Tesla();
        }
        else {
            return null;
        }
    }

//    方法2
    public static Car getFerrari(){
        return new Ferrari();
    }
    public static Car getTesla(){
        return new Tesla();
    }
}

静态工厂模式存在的问题是若扩展车的种类,则必须修改Carfactory的代码,不满足开闭原则。

工厂方法模式

在静态工厂模式的基础上,增加了工厂接口,那么扩展车种类时,只需要根据根据Car和CarFactory接口实现各自的车和各自工厂,不需要修改原代码,实现了动态扩展。
在这里插入图片描述

public class Consumer {
    public static void main(String[] args) {
        Car car1 = new TelsaFactory().getCar();
        Car car2 = new FerrariFactory().getCar();
    }
}

public interface CarFactory {
    Car getCar();
}
public class FerrariFactory implements CarFactory {
    @Override
    public Car getCar() {
        return new Ferrari();
    }
}
public class TelsaFactory implements CarFactory{
    @Override
    public Car getCar() {
        return new Tesla();
    }
}

抽象工厂模式

在这里插入图片描述
当一个问题如上即涉及多个产品等级,且等级较为固定。
在这里插入图片描述
这里就放几个接口

public class Client {
    public static void main(String[] args) {
        System.out.println("============Ferrari==============");
        ProductFactory ferrariFactory = new FerrariFactory();

        Engine engine=ferrariFactory.produceEngine();
        engine.power();

        Wheel wheel=ferrariFactory.produceWheel();
        wheel.materia();
        wheel.size();

        System.out.println("============Tesla==============");
        ProductFactory teslaFactory=new TeslaFactory();

        Engine engine1=teslaFactory.produceEngine();
        engine1.power();

        Wheel wheel1=teslaFactory.produceWheel();
        wheel1.materia();
        wheel1.size();
    }
}
public interface Engine {
    void power();
}
public interface Wheel {
    void materia();
    void size();
}
//抽象产品工厂
public interface ProductFactory {
//    生产发动机
    Engine produceEngine();
//    生产轮胎
    Wheel produceWheel();
}

原型模式

克隆模式即复制粘贴,可直接由Cloneable接口的native方法clone()实现
但原本的clone()由底层实现所以只是浅复制,要想实现深度复制需修改clone()代码。
一般工厂模式可与克隆模式结合。

import java.util.Date;

public class Prototype implements Cloneable{
    private String name;
    private Date date;

    @Override
    protected Object clone() throws CloneNotSupportedException {
//        浅复制
        return super.clone();
        
//        深度复制
//        Object obj=super.clone();
//        Prototype temp=(Prototype) obj;
//        temp.date=(Date)this.date.clone();
//        return obj;
    }

    public Prototype(String name,Date date) {
        this.name = name;
        this.date = date;
    }

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

    public static void main(String[] args) throws CloneNotSupportedException{
        Date date=new Date();
        Prototype prototype1=new Prototype("我是名字",date);
        Prototype prototype2=(Prototype)prototype1.clone();
//      由hashCode可以得出两者完全一样
        System.out.println("prototype1->"+prototype1+" hashCode->"+prototype1.hashCode());
        System.out.println("prototype2->"+prototype2+" hashCode->"+prototype2.hashCode());
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值