设计模式(GOF23)

设计模式(GOF23)

设计模式共23种,根据功能划分为创建型,结构性,行为行三种类型模式

正确使用设计模式使程序更加标准化,提高编程思维和能力,使代码的可重用性高,可读性强,可维护性强

创建型

工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

达到创建、使用分离效果

工厂模式

定义一个用于创建对象的接口,子类想要什么对象就去调用创建该对象的接口方法

1.简单工厂

/**
 * 简单工厂模式
 * 违背开闭原则
 */
public class BinGanFactory {
    //方法一
    public static BinGan getBinGan(String s){
        if ("旺旺".equals(s)){
            return new WangWang();
        }if("奥利奥".equals(s)){
            return new AoLiAo();
        }else {
            return null;
        }
    }
//    方法二
    public static BinGan getWangWang(){
        return new WangWang();
    }
    public static BinGan getAoLiAo(){
        return new AoLiAo();
    }
}
//好处,代码简单干净
//坏处,无法拓展

2.工厂方法

解决简单工厂不能扩展的问题

/*工厂方法模式,将工厂抽象,自定义需要拓展的工厂类型*/
public interface BinGanFactory {
    BinGan getBinGan();
}

public class QiQuFactory implements BinGanFactory {
    @Override
    public BinGan getBinGan() {
        return new QiQu();
    }
}
public class QiQu implements BinGan {
    @Override
    public void name() {
        System.out.println("奇趣饼干");
    }
}

抽象工厂模式

工厂方法:多态性工厂,如要加入新的对象,加入新的工厂类就行了,以前的不用修改
抽象工厂:和工厂方法最大区别是对多个产品族

public interface FoodFactory {
    BinGan getBinGan();
    XueGao getXueGao();
}

public class AoLiAoFactory implements FoodFactory {
    @Override
    public BinGan getBinGan() {
        return new AoLiAo();
    }

    @Override
    public XueGao getXueGao() {
        return new AoLiAoXueGao();
    }
}

单例模式

饿汉式

/**
 * 饿汉式
 */
public class Hungry {
    private int[] arr1=new int[1024*1024];
    private int[] arr2=new int[1024*1024];
    //    私有空参构造,防止子类调用创建
    private Hungry(){};

    public static Hungry getInstance(){
        return new Hungry();
    }
}

懒汉式

/**
 * 懒汉式
 */
public class LazyMan {
    private int[] arr1=new int[1024*1024];
    private int[] arr2=new int[1024*1024];
    //volatile避免指令重排
    private volatile static LazyMan lazyMan;
    //  只要是单例模式都私有构造器
    private LazyMan(){};

    //线程不安全
	/*  public static LazyMan getInstance(){
        if (lazyMan==null){
            return new LazyMan();
        }
        return lazyMan;
    }*/
    //使用双重检测锁模式结局线程安全
    public static LazyMan getInstance(){
        if (lazyMan==null){
            synchronized (LazyMan.class){
                if (lazyMan==null){
                    return new LazyMan();//不是原子操作
                    /*new 创建对象
                    * 1.分配内存空间
                    * 2.执行构造方法,初始化对象
                    * 3.把对象指向空间
                    * 123
                    * 132
                    * 使用了volatile,防止对象还没初始化就指向了空间
                    * */
                }
            }
        }
        return lazyMan;
    }
}

建造者模式

封装一个复杂对象构造过程,并允许按步骤构造

/**
 * 建造者模式
 * 抽象建造者:方法、过程
 */
public interface Builder {
    void buildA(); //地基
    void buildB(); //钢筋工程
    void buildC(); //电线
    void buildD(); //粉刷

    Product over(); //完工
}

/**
 * 高楼工人
 */
public class Worker implements Builder {

    private Product product;

    public Worker() {
        product=new Product();
    }

    @Override
    public void buildA() {
        System.out.println("工人开始打高楼地基");
        product.setA("地基");

    }

    @Override
    public void buildB() {
        System.out.println("工人开始做高楼钢筋水泥");
        product.setA("钢筋工程");
    }

    @Override
    public void buildC() {
        System.out.println("工人铺高楼电线");
        product.setC("电线");
    }

    @Override
    public void buildD() {
        System.out.println("工人开始高楼粉刷");
        product.setD("粉刷");
    }

    @Override
    public Product over() {
        return product;
    }
}

//指挥,导演。    指挥建造者如何构建产品。控制调用先后顺序
public class Director {
    public Product build(Builder builder){
        
        //具体步骤顺序
        builder.buildA();
        builder.buildB();
        builder.buildC();
        builder.buildD();

        return builder.over();
    }
}

public class Product {
    private String a;
    private String b;
    private String c;
    private String d;
}

//--------测试--------
 public static void main(String[] args) {
        Director director = new Director();
        Product build = director.build(new Worker());
        System.out.println(build.toString());
    }
  • 应用场景

    • 生成的产品对象有复杂的结构,且这些产品有共性
    • 隔离复杂对象的创建和使用,并使的相同的创建过程可以创建不同的产品
  • 建造者模式和抽象工厂模式区别

    • 抽象工厂返回的使一个产品族的一系列产品。建造者模式返回的使一个组装好的完整产品
    • 抽象工厂调用工厂(建造者)方法获取对象,建造者指挥director.build(new Worker());给我对象,不直接调用建造者的相关方法
    • 如果将抽象工厂看成汽车配件生产工厂,生产一个产品族(汽车配件)的产品,那么建造者模式就是汽车组装工厂。

原型模式

需要一个原型对象,通过克隆原型对象来获取新对象

/**
 * 原型模式
 * 1.实现一个接口 Cloneable
 * 2.重写一个方法 clone
 */
public class Video implements Cloneable{
    private String name;
    private Date createTime;

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

		//原型对象
        Date date = new Date();
        Video video = new Video();
        video.setCreateTime(date);
        System.out.println(video);
        //克隆
        Video clone = (Video) video.clone();
		

public class Video implements Cloneable{
    private String name;
    private Date createTime;
    @Override
    protected Object clone() throws CloneNotSupportedException {
        //实现深克隆:改造克隆方法
        Video clone = (Video) super.clone();
        //将引用也克隆一份
        clone.createTime= (Date) this.createTime.clone();
        return clone;
    }
}

结构型

适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式

适配器模式

将某个类的接口转换成客户端期望的另一个接口表示,使得原本由于接口不兼容而不能一起工作的类能一起工作。

角色:适配器,需要被适配的类,适配目标

继承方式:

public interface NetToUsb {
    void handleRequest();
}
//适配器
public class Adapter extends Adaptee implements NetToUsb{
    @Override
    public void handleRequest() {
        super.request(); //可以上网了
    }
}

/**
 * 要被适配的类:网线
 */
public class Adaptee {
    void request(){
        System.out.println("连接网线上网");
    }
}

//目标
public class Computer {
    void net(NetToUsb adapter){
        //上网的具体实现,找一个转接头
        adapter.handleRequest();
    }
    public static void main(String[] args) {
        //继承
        Computer computer = new Computer();//电脑
        Adapter adapter = new Adapter();//适配器(由于继承,适配器化身网线了)
        computer.net(adapter);
    }
}

//弊端:单继承

组合方式:

public class Adapter2 implements NetToUsb{
    private Adaptee adaptee;

    public Adapter2(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void handleRequest() {
        adaptee.request(); //可以上网了
    }
}

public class Computer {

    void net(NetToUsb adapter){
        //上网的具体实现,找一个转接头
        adapter.handleRequest();
    }

    public static void main(String[] args) {
        //继承
//        Computer computer = new Computer();//电脑
//        Adapter adapter = new Adapter();//适配器
//        computer.net(adapter);

        //组合
        Computer computer = new Computer();//电脑
        Adaptee adaptee = new Adaptee();//网线
        Adapter2 adapter2 = new Adapter2(adaptee);//适配器
        computer.net(adapter2);
    }
}

桥接模式

一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时,使用桥接模式关联两个维度

public interface Brand {
    void info();
}

public class Apple implements Brand{
    @Override
    public void info() {
        System.out.print("苹果");
    }
}

public abstract class Computer {
    protected Brand brand;

    public Computer(Brand brand) {
        this.brand = brand;
    }

    public void info(){
        brand.info();
    }
}

class Desktop extends Computer{

    public Desktop(Brand brand) {
        super(brand);
    }

    @Override
    public void info() {
        super.info();
        System.out.print("台式机");
    }
}

public class Test {
    public static void main(String[] args) {
        //苹果笔记本
        //桥接了品牌和产品信息
        Apple apple = new Apple();
        Computer desktop = new Desktop(apple);
        desktop.info();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值