2023/7/15·一些设计模式(Java)

1 · 单例模式

单例模式 指某一个类只能实例化一个对象的设计模式,单例模式分为 懒汉式饿汉式,顾名思义,懒汉式 不到最后一刻是不会初始化对象的,而 饿汉式 的创建对象和初始化对象都会在第一时间完成。

public class Student {
    //单例模式 饿汉式
    static Student student = new Student(); //创建对象即初始化
    
    private Student() {		//私有化构造,防止外部创建对象
    }
    
    public static Student getStudent() {	//获取对象的方法
        return student;
    }
    
    public void study() {
        System.out.println("学习");
    }
}
public class Student {
    //单例模式 懒汉式
    static Student student; 

    private Student() {
    }
    
    public static Student getStudent() {
        if (student == null)            
            student = new Student();	//需要获取对象时才初始化
        return student;
    }
    
    public void study() {
        System.out.println("学习");
    }
}

2 · 简单工厂模式

简单工厂模式 又称 静态工厂模式,不同于 单例模式,工厂模式一般适用于创建对象的种类较多,可以归属于同一体系下时,可以考虑使用工厂模式来进行整个继承体系对象的同一创建,这样就不需要给每个单独的子类提供一个创建的方法。

这里创建了一个 Game 接口

public interface Game {
    public void getGameName();
}

再创建两个类 EldenRingDevilMayCry 实现 Game 接口

public class EldenRing implements Game {
    private String name = "艾尔登法环";

    @Override
    public void getGameName() {
        System.out.println(name);
    }
}
public class DevilMayCry implements Game {
    private String name = "鬼泣";

    @Override
    public void getGameName() {
        System.out.println(name);
    }
}

最后创建 Steam 类,也就是“工厂”

public class Steam {
    //工厂模式
    public static Game getGame(String name) {	//接受游戏名参数,返回接口类型的对象
        if ("艾尔登法环".equals(name)) {
            return new EldenRing();
        } else if ("鬼泣".equals(name)) {
            return new DevilMayCry();
        }
        return null;
    }
}

测试一下,控制台成功输出艾尔登法环的getGameName()方法

public class test {
    public static void main(String[] args) {
        EldenRing eldenRing = (EldenRing) Steam.getGame("艾尔登法环");
        eldenRing.getGameName();
        //艾尔登法环
    }
}

3 · 静态代理模式

代理模式包含如下角色:
抽象主题(Subject):通过接口或抽象类声明业务方法。
真实主题 (Real Subject):实现了抽象主题中的具体业务,是实施代理的目标对象,即代理对象所代表的真实对象,是最终要引用的对象。
代理(Proxy):提供了与真实主题相同的接口,其内部含有对真实主题的引用,可以访问、控制或拓展真实主题的功能。
这里创建一个People接口,这是抽象主题

public interface People {
    //人都会交流
    public void talk();

}

再创建Student类和Gamer类实现People接口,各自重写talk() 方法,这里Gamer是代理,所以在Gamer类中添加一个People属性,新建一个参数为People接口的构造器,构造器用于接收真实主题的对象,再在talk()方法内调用真实主题对象的talk方法,这就形成了代理模式。

public class Student implements People{
    @Override
    public void talk() {
        System.out.println("学生说话");
    }
}
public class Gamer implements People {
    private People p;

    public Gamer() {
    }

    //初始化时,接受代理人
    public Gamer(People p) {
        this.p = p;
    }

    @Override
    public void talk() {
        p.talk();   //执行代理人自己的方法
        System.out.println("玩家讲话");
    }
}

这里简单运行一下,可以看到以Student以Gamer的身份同事调用了两个talk()方法

public class test {
    public static void main(String[] args) {
        Gamer gamer = new Gamer(new Student());
        gamer.talk();
    }
}
//    学生说话
//    玩家讲话

4 · 适配器模式(类适配器)

适配器模式 包含如下角色:
目标角色(Target),被转换后的目标接口。
源角色(Adaptee),需要被转换的接口。
适配器(Adapter),负责将Adaptee转换为Target。

创建目标角色:

public interface GameController { //手柄
    String outControllerSignal();   //输出手柄信号
}

源角色:

public class KeyboardMouse { //键鼠
    public String outKMSignal(){
        return "键鼠信号";
    }
}

适配器:

public class Translator extends KeyboardMouse implements GameController{    //键鼠转换器+
    @Override
    public String outControllerSignal() {
        String signal = super.outKMSignal();    //获得键鼠信号
        String finalSignal = signal +"(已转换为手柄信号)";      //适配过程
        System.out.println("已将"+signal+"转换为手柄信号");
        return finalSignal;
    }
}

测试,获得了转换之后的键鼠信号

public class test {
    public static void main(String[] args) {
        Translator translator = new Translator();
        System.out.println(translator.outControllerSignal());
        //已将键鼠信号转换为手柄信号
        //键鼠信号(已转换为手柄信号)
    }
}

5 · 原型模式

原型模式通过对Object类的clone() 方法重写来实现对象的重复创建,用于大量创建重复对象,而不需要指定细节(属性、方法等等)。

这里用星战的例子创建一个克隆人士兵类(CloneTrooper) ,实现Cloneable 接口,才能拥有复制的能力。
还有用于基因原型的人类(Human)

//克隆士兵类
public class CloneTrooper implements Cloneable {     //克隆人士兵
    private Human geneticPrototype;  //基因原型

    public CloneTrooper() {
    }

    public CloneTrooper(Human geneticPrototype) {
        this.geneticPrototype = geneticPrototype;
    }

    public void execute(int num) {      //执行命令的方法
        System.out.println("执行" + num + "号密令");
    }

    //重写clone方法,实现对原型的复制
    @Override
    protected Object clone() {
        CloneTrooper cloneTrooper = null;
        try {
            cloneTrooper = (CloneTrooper) super.clone();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return cloneTrooper;
    }

    public Human getGeneticPrototype() {
        return geneticPrototype;
    }

    public void setGeneticPrototype(Human geneticPrototype) {
        this.geneticPrototype = geneticPrototype;
    }
}
//人类
public class Human {
    private String name;

    public Human(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

测试,创建基因原型詹戈菲特,创建第一个克隆人士兵,能够执行拥有的方法;再用clone() 方法克隆2号和3号克隆人士兵,分别执行66号密令和原型及其哈希码,可以看到原型都是同一个对象,省去了繁琐的初始化对象操作。

public class test {
    public static void main(String[] args) {
        Human JangoFett = new Human("Jango Fett");       //创建基因原型
        CloneTrooper trooper1 = new CloneTrooper(JangoFett);     //复制第一个克隆士兵
        trooper1.execute(66);        //执行66号密令
        System.out.println("基因原型:"+trooper1.getGeneticPrototype().getName()+" 哈希码:"+trooper1.getGeneticPrototype().hashCode());
        CloneTrooper trooper2 = (CloneTrooper) trooper1.clone();         //实际上克隆人都是由基因克隆而不是第一个克隆人的基因,这里就不忠于原著了
        trooper2.execute(66);
        System.out.println("基因原型:"+trooper2.getGeneticPrototype().getName()+" 哈希码:"+trooper2.getGeneticPrototype().hashCode());
        CloneTrooper trooper3 = (CloneTrooper) trooper1.clone();
        trooper2.execute(66);
        System.out.println("基因原型:"+trooper3.getGeneticPrototype().getName()+" 哈希码:"+trooper3.getGeneticPrototype().hashCode());
        //执行66号密令
        //基因原型:Jango Fett 哈希码:460141958
        //执行66号密令
        //基因原型:Jango Fett 哈希码:460141958
        //执行66号密令
        //基因原型:Jango Fett 哈希码:460141958
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值