设计模式—创建型

  • 学习思想

单例模式

工厂模式

1.简单工厂模式(静态工厂模式)

  • 概述
1.不向客户端暴露创建对象逻辑,提供公共接口指向创建的对象
2.调用者创建对象,只需要知道该对象的名称
3.每次增加产品都要增加具体产品类和工厂类中else-if,不满足开闭原则,工厂方法模式解决该问题,但一般情况下简单工厂模式使用的较多
  • 类图
    在这里插入图片描述
  • 讲解
1.实现Shape接口实现Shape接口的实体类
2.定义工厂类ShapeFactory,根据传入的类型名创建Shape的具体实现类
3.FactoryPatternDemo类使用ShapeFactory来获取Shape对象,它将向ShapeFactory传递信息
  • 实现
//1.创建产品接口
public interface Shape{
	void draw();
}
//2.创建具体产品类
public class Circle implements Shape {
	@Override
    public void draw() {
    	System.out.println("Circle-draw");
   }
}
public class Square implements Shape {
	@Override
    public void draw() {
    	System.out.println("Square-draw");
    }
}
public class Rectangle implements Shape{
	@Override
    public void draw() {
	    System.out.println("Rectangle-draw");
    }
}
//3.创建工厂用于实例化对象—只需要知道产品名
public class ShapeFactory {
   public Shape getShape(String shapeType){
      if(shapeType == null) return null;     
      
      if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();
      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();
      } else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }
      return null;
   }
}
----------------------------------------
main(){
	//原来的调用方式
	Shape circle1 = new Circle();
 	Shape square1 = new Square();
    Shape rectangle1 = new Rectangle();
    circle1.draw();
    square1.draw();
    rectangle1.draw();
	//如果形状有很多参数或其他则不方便,需要使用简单工厂模式
	----------------------
	//静态工厂获取
	Shape circle2 = ShapeFactory.getShape("Circle");
    Shape square2 = ShapeFactory.getShape("Square");
    Shape rectangle2 = ShapeFactory.getShape("Rectangle");
    circle2.draw();
    square2.draw();
    rectangle2.draw();
}

2.工厂方法模式

  • 概述
1.解决简单工厂不满足开闭原则的问题,每次增加产品只需扩展相应的产品工厂实现工厂类即可
2.在简单工厂基础上对每个产品建立对应的工厂实现类来创建对应的产品
3.类的数量大大增加
  • 类图
    在这里插入图片描述
  • 实现
//1.创建产品接口
public interface Shape{
	void draw();
}
//2.创建具体产品类
public class Circle implements Shape {
	@Override
    public void draw() {
    	System.out.println("Circle-draw");
   }
}
public class Square implements Shape {
	@Override
    public void draw() {
    	System.out.println("Square-draw");
    }
}
public class Rectangle implements Shape{
	@Override
    public void draw() {
	    System.out.println("Rectangle-draw");
    }
}
//3.创建工厂
public interface ShapeFactory {
    Shape getShape();
}
//4.创建产品的具体工厂
public class CircleFactory implements ShapeFactory {
    @Override
    public Shape getShape() {
        return new Circle();
    }
}
public class RectangleFactory implements ShapeFactory {
    @Override
    public Shape getShape() {
        return new Circle();
    }
}
public class SquareFactory implements ShapeFactory {
    @Override
    public Shape getShape() {
        return new Square();
    }
}
----------------------------------------
main(){
    //工厂方法创建方式
   	Shape circle1 = new CircleFactory().getShape();
   	Shape square1 = new SquareFactory().getShape();
   	Shape rectangle1 = new RectangleFactory().getShape();
   	circle1.draw();
   	square1.draw();
   	rectangle1.draw();
}

  • 比较简单工厂与工厂方法模式
1.结构复杂度:simple
2.代码复杂度:simple
3.编程复杂度:simple
4.管理复杂度:simple

根据设计模式:工厂方法模式
根据实际业务:简单工厂模式
学习思想,不一定满足设计原则,但是实际应用的更多

3.抽象工厂模式

  • 概述
1.围绕超级工厂创建其他工厂(工厂的工厂),接口主要负责创建相应对象的工厂,但上边两种模式是创建产品的
2.无需关心创建细节,将同一系列产品一起创建
3.违反开闭原则,产品稳定的话使用抽象工厂更佳,否则难以维护,不如使用简单工厂模式
  • 区分产品族与产品等级
    在这里插入图片描述
  • 类图
    在这里插入图片描述
  • 实现
//1.两个产品等级接口--手机+路由器
public interface IphoneProduct {
    void start();
    void shutdown();
    void call();
}
public interface IrouterProduct {
    void start();
    void shutdown();
    void openwifi();
}
//2.小米华为分别实现这两个产品
public class XiaomiPhone implements IphoneProduct {//小米手机
    @Override
    public void start() {
        System.out.println("小米手机开机");
    }
    @Override
    public void shutdown() {
        System.out.println("小米手机关机");
    }
    @Override
    public void call() {
        System.out.println("小米手机打电话");
    }
}
public class HuaweiPhone implements IphoneProduct {//华为手机
    @Override
    public void start() {
        System.out.println("华为手机开机");
    }
    @Override
    public void shutdown() {
        System.out.println("华为手机关机");
    }
    @Override
    public void call() {
        System.out.println("华为手机打电话");
    }
}
public class XiaomiRouter implements IrouterProduct {//小米路由器
    @Override
    public void start() {
        System.out.println("小米路由器开机");
    }
    @Override
    public void shutdown() {
        System.out.println("小米路由器关机");
    }
    @Override
    public void openwifi() {
        System.out.println("小米路由器打开WiFi");
    }
}
public class HuaweiRouter implements IrouterProduct {//华为路由器
    @Override
    public void start() {
        System.out.println("华为路由器开机");
    }
    @Override
    public void shutdown() {
        System.out.println("华为路由器关机");
    }
    @Override
    public void openwifi() {
        System.out.println("华为路由器打开WiFi");
    }
}
//3.抽象工厂--产品族工厂
public interface AbstractProductFactory {
    //生产手机
    IphoneProduct iphoneProduct();
    //生产路由器
    IrouterProduct irouterProduct();
}
//4.小米与华为的产品族工厂
public class XiaomiFactory implements AbstractProductFactory {
    @Override
    public IphoneProduct iphoneProduct() {
        return new XiaomiPhone();
    }
    @Override
    public IrouterProduct irouterProduct() {
        return new XiaomiRouter();
    }
}
public class HuaweiFactory implements AbstractProductFactory {
    @Override
    public IphoneProduct iphoneProduct() {
        return new HuaweiPhone();
    }
    @Override
    public IrouterProduct irouterProduct() {
        return new HuaweiRouter();
    }
}
----------------------------------------
main(){
	System.out.println("===小米系列===");
    XiaomiFactory xiaomiFactory = new XiaomiFactory();
    IphoneProduct xiaomiPhone = xiaomiFactory.iphoneProduct();
    xiaomiPhone.start();
    IrouterProduct xiaomiRouter = xiaomiFactory.irouterProduct();
    xiaomiRouter.start();

    System.out.println("===华为系列===");
    HuaweiFactory huaweiFactory = new HuaweiFactory();
    IphoneProduct huaweiPhone = huaweiFactory.iphoneProduct();
    huaweiPhone.start();
    IrouterProduct huaweiRouter = huaweiFactory.irouterProduct();
    huaweiRouter.start();
}

建造者模式

  • 概述
1.用于构建复杂对象,子对象常由算法构成,由于需求变化,复杂对象的各个子对象面临剧烈变化,但将子对象组合的算法相对稳定
2.将变与不变分离,符合开闭原则
3.产品差异较大就不能使用,适用于有较多属性(零件)的对象(产品)的创建过程
  • 类图
    在这里插入图片描述
  • 讲解
盖房子需要建筑公司或承包商(指挥者),承包商指挥工人(具体建造者)怎样造房子
  • 实现—有指挥者
//1.产品
public class Product {
    private String buildA;
    private String buildB;
    private String buildC;
    private String buildD;
    
	set+get
}
//2.抽象的建造者:建造方法,工人需要 地基 - 钢筋 - 电线 - 粉刷
public abstract class Buider {
    abstract void buildA();//地基
    abstract void buildB();//钢筋
    abstract void buildC();//电线
    abstract void buildD();//粉刷

    //以上是构建产品的四个步骤,最后会生成产品
    abstract Product getProduct();
}
//3.工人:具体的建造房子,建造好后返回一个具体的产品
//此时工人要做的事情都已经准备好了,但是工人不知道要先干什么,那么此时需要一个指挥者Director
public class Worker extends Buider {
    private Product product;

    public Worker() {
        //此处的产品不是传进来的,而是工人建造的,注意是new出来的
        this.product = new Product();
    }
    @Override
    void buildA() {
        product.setBuildA("地基");
        System.out.println("地基");
    }
    @Override
    void buildB() {
        product.setBuildB("钢筋");
        System.out.println("钢筋");
    }
    @Override
    void buildC() {
        product.setBuildC("电线");
        System.out.println("电线");
    }
    @Override
    void buildD() {
        product.setBuildD("粉刷");
        System.out.println("粉刷");
    }
    @Override
    public Product getProduct() {
        return product;
    }
}
//4.核心:指挥工人如何构建房子
public class Director {
    //指挥建房子,建好后返回建好的房子---核心构建顺序
    public Product build(Buider buider) {
        buider.buildA();
        buider.buildB();
        buider.buildC();
        buider.buildD();

        return buider.getProduct();
    }
}
----------------------------------------
main(){
	//指挥
	Director director = new Director();
	//具体工人构建产品
	Product product = director.build(new Worker());
	System.out.println(product.toString());
}
  • 实现—无指挥者
//1.套餐
public class Product {
    //默认套餐
    private String buildA = "汉堡";
    private String buildB = "可乐";
    private String buildC = "薯条";
    private String buildD = "甜点";

    //get/set方便用户随意搭配套餐
    set/get
}
//2.抽象的建造者:建造方法
//指挥者的角色应该是客户自己,例如KFC的套餐搭配,选怎样的套餐由客户决定,怎样制作由服务员决定
public abstract class Buider {
    abstract Buider buildA(String msg);//汉堡
    abstract Buider buildB(String msg);//可乐
    abstract Buider buildC(String msg);//薯条
    abstract Buider buildD(String msg);//甜点

    //以上是产品的四个搭配方式,最后会按客户的意思生成产品
    abstract Product getProduct();
}
//3.服务员
public class Worker extends Buider {
    private Product product;

    public Worker() {
        //此处的产品不是传进来的,而是工人建造的,注意是new出来的
        this.product = new Product();
    }

    @Override
    Buider buildA(String msg) {
        product.setBuildA(msg);
        return this;
    }
    @Override
    Buider buildB(String msg) {
        product.setBuildB(msg);
        return this;
    }
    @Override
    Buider buildC(String msg) {
        product.setBuildC(msg);
        return this;
    }
    @Override
    Buider buildD(String msg) {
        product.setBuildD(msg);
        return this;
    }
    @Override
    public Product getProduct() {
        return product;
    }
}
----------------------------------------
main(){
	Worker worker = new Worker();//服务员
	Product product = worker.getProduct();//产品
	System.out.println(product.toString());
	System.out.println("===================");
	//链式编程,客户想要什么服务员就做什么,但是不组合也有默认套餐
	product = worker.buildA("全家桶").buildB("雪碧").getProduct();
	System.out.println(product.toString());
}

原型模式

  • 概述
1.创建重复对象的同时保证性能
2.原型对象用于创建该对象的克隆,因为直接创建对象的代价太大,克隆对象在运行期间创建和删除
  • 实现—浅拷贝
    在这里插入图片描述
/**
 - 视频类-->视频总是被盗取
 - 实现克隆-->实现接口Cloneable+重写方法clone
 - <p>
 - 浅克隆:引用类型只是赋值,但是指向同一个Date.当Date变化时,二者都变,所以理想状态是深克隆
 */
public class Video implements Cloneable {
    private String name;
    private Date createTime;

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

    //构造器+set/get+toString
}
  • 实现—深拷贝
    在这里插入图片描述
/**
 - 视频类-->视频总是被盗取
 - 实现克隆-->实现接口Cloneable+重写方法clone
 - <p>
 - 深克隆
 */
public class Video implements Cloneable {
    private String name;
    private Date createTime;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        //改造成深克隆
        Video video = (Video) super.clone();
        //将这个对象的属性也克隆一份
        video.createTime = (Date) this.createTime.clone();
        return video;
    }
	
	//构造器+set/get+toString
}
  • 测试
/**
 * 无良up盗取视频
 */
public class Bilibili {
    public static void main(String[] args) throws CloneNotSupportedException, InterruptedException {
        Date date = new Date();

        //原视频
        Video prototype = new Video("狂神说", date);
        System.out.println("原型:" + prototype);
        System.out.println("hash:" + prototype.hashCode());

        //盗取克隆视频
        Video clone = (Video) prototype.clone();
        System.out.println("克隆:" + clone);
        System.out.println("hash:" + clone.hashCode());

        //观察二者hash发现确实是不同的对象,但是属性值相同

        //盗取视频的修改名称后重新发布
        clone.setName("我的视频");
        System.out.println(clone);

        System.out.println();

        //浅克隆与深克隆问题
        date.setTime(311565611);
        System.out.println("原型:" + prototype);
        System.out.println("克隆:" + clone);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值