java常用设计模式总结

java常用设计模式总结

1、工厂模式

作用:1、一些类的构造方法中的参数非常之多,传参容易出错、非常繁琐,维护也很麻烦

2、有时我们想要创建一个对象实现相应功能需要创建很多的对象,这时把创建对象的操作放在工厂中,由工厂代替我们来创建这些对象,避免重复造轮子。

例如:现在有很多的电子产品代工厂,不同的厂商都可以把自己的产品放在这个工厂中去建造,需要产品时,只需要向工厂中去拿,并告诉工厂你想要哪个品牌的产品即可,而不是每次都去找不同的品牌制造商去买。

1.1简单工厂

例如:想要买到不同品牌的耳机

1.1.1 创建耳机接口,并提供制造耳机的抽象方法:
public interface Headset {
    void makeHeadSet();
}
1.1.2 小米和华为等不同品牌的耳机来继承耳机接口:
public class XiaoMiHeadset implements Headset {
    @Override
    public void makeHeadSet() {
        System.out.println("工厂正在制造小米牌子的耳机");
        System.out.println("成功获得小米牌子的耳机");
    }

}

public class HuaWeiHeadset implements Headset {
    @Override
    public void makeHeadSet() {
        System.out.println("工厂正在制造华为牌子的耳机");
        System.out.println("成功获得华为牌子的耳机");
    }
}
1.1.3 创建代工厂类,代工厂帮忙制造耳机:
public class ChinaFactory {
    public ChinaFactory() {
    }
	//工厂中提供制造耳机的方法,参数为耳机的品牌,并返回耳机对象
    public Headset makeHeadset(String brandName){
        if (brandName==null){
            return null;
        }else if(brandName.equals("小米")){
            return new XiaoMiHeadset();
        }else if(brandName.equals("华为")){
            return new HuaWeiHeadset();
        }else {
            return null;
        }
    }
}
1.1.4 创建测试类,从工厂中买到耳机
public class TestFactory {
    public static void main(String[] args) {
        BuyHeadset("小米");
    }
    /**
     * 买耳机
     * @param brandName 耳机品牌名
     */
    static void BuyHeadset(String brandName){
        ChinaFactory chinaFactory=new ChinaFactory();
        Headset headset=chinaFactory.makeHeadset(brandName);
        headset.makeHeadSet();
    }
}
1.1.5 结果

在这里插入图片描述

1.2 工厂方法模式

在简单工厂模式种我们发现,这个工厂需要负责所有产品的代生产,工厂方法模式将生产不用品牌产品的工厂分给不同的工厂

耳机接口和不同耳机的实体类都不变

1.2.1 创建抽象工厂接口
public interface AbstractFactory {    
    Headset makeHeadset();
}
1.2.2 创建生产小米产品的工厂
public class XiaoMiFactory implements AbstractFactory {
    @Override
    public Headset makeHeadset() {
        return new XiaoMiHeadset();
    }
}
1.2.3 创建生产华为产品的工厂
public class HuaWeiFactory implements AbstractFactory {
    @Override
    public Headset makeHeadset() {
        return new HuaWeiHeadset();
    }
}
1.2.4 测试
public class TestFactory {
    public static void main(String[] args) {
        BuyHeadset();
    }
    /**
     * 买耳机
     */
    static void BuyHeadset(){
        //只需直接找到华为的代工厂即可
        AbstractFactory abstractFactory=new HuaWeiFactory();
        Headset headset=abstractFactory.makeHeadset();
        headset.makeHeadSet();
    }
}
1.2.5 结果

在这里插入图片描述

1.3 抽象工厂模式

以上两种的工厂方式都是只针对一种产品的制造,小米和华为有很多的产品:手机、电脑、平板等等。。

我们只需继续编写实体类,并将响应产品的制造放入相应品牌的制造工厂中即可

现在新增手机的生产

1.3.1 产品接口和实体类
public interface PC {
    void  makePC();
}
public class XiaoMiPC implements PC {
    @Override
    public void makePC() {
        System.out.println("小米电脑生产");
    }
}
public class HuaWeiPC implements PC {
    @Override
    public void makePC() {
        System.out.println("华为电脑生产");
    }
}

1.3.2 在抽象工厂中添加PC的制造方法
public interface AbstractFactory {
    Headset makeHeadset();
    PC makePc();
}

public class HuaWeiFactory implements AbstractFactory {
    @Override
    public Headset makeHeadset() {
        return new HuaWeiHeadset();
    }

    @Override
    public PC makePc() {
        return new HuaWeiPC();
    }
}

public class XiaoMiFactory implements AbstractFactory {
    @Override
    public Headset makeHeadset() {
        return new XiaoMiHeadset();
    }

    @Override
    public PC makePc() {
        return new XiaoMiPC();
    }
}
1.3.3 测试
public class TestFactory {
    public static void main(String[] args) {
        System.out.println("生产耳机:");
        BuyHeadset();
        System.out.println("生产PC:");
        BuyPC();
    }

    /**
     * 买耳机
     */
    static void BuyHeadset(){
        AbstractFactory abstractFactory=new HuaWeiFactory();
        Headset headset=abstractFactory.makeHeadset();
        headset.makeHeadSet();
    }

    /**
     * 买电脑
     */
    public static void BuyPC(){
        AbstractFactory abstractFactory=new XiaoMiFactory();
        PC pc=abstractFactory.makePc();
        pc.makePC();
    }
}
1.3.4 结果

在这里插入图片描述

2、单例模式

单例模式即每个类只能有一个实例化的对象,可以避免某个频繁使用的类被频繁创建、销毁,节省资源消耗。

例如:每个班级只能有一个班主任,当校长、领导、教育局都想看某个老师的简历的时候,虽然每个人都拿到了一份简历(对象的引用),但是这几份简历都指向的是同一个老师(同一个对象)

单例模式的要求:

1、单例类只能有一个实例。

2、单例类必须自己创建自己的唯一实例。

3、单例类必须给所有其他对象提供这一实例。

2.1 饿汉式(类加载的时候直接创建对象)

容易产生垃圾对象,但执行效率比较高,多线程安全

public class Teacher {
    private String name="张三";
    private int age=18;
    //类内部直接创建对象
    private static Teacher teacher=new Teacher();
    //私有无参构造方法
    private Teacher(){}
    public static Teacher getInstance(){
        return teacher;
    }
    public String getName() {return name;}
    public int getAge() { return age;}
    public void setName(String name) {this.name = name;}
    public void setAge(int age) {this.age = age;}
}

测试

public class Test {
    public static void main(String[] args) {
        //教育局来看老师的简历
        Teacher teacher=Teacher.getInstance();
        System.out.println("教育局看到老师的阿名字为:"+teacher.getName());
        //现在校长来看老师的简历
        Teacher teacher1=Teacher.getInstance();
        System.out.println("校长看到的老师名字为:"+teacher1.getName());

    }
}

结果
在这里插入图片描述

2.2 懒汉式(在调用getInstance()方法时才去创建对象)
public class Teacher {
    private String name="张三";
    private int age=18;
    private static Teacher teacher;
    private Teacher(){

    }
    //在这里加上synchronized关键字修饰成为线程安全的单例模式
    /**
     * public static synchronized Teacher getInstance(){
     *         if (teacher==null) {
     *             return teacher=new Teacher();
     *         }
     *         return teacher;
     *     }
     */
    public static Teacher getInstance(){
        if (teacher==null) {
            return teacher=new Teacher();
        }
        return teacher;
    }

    public String getName() {return name;}
    public int getAge() { return age;}
    public void setName(String name) {this.name = name;}
    public void setAge(int age) {this.age = age;}
}

3、建造者模式

对某些类的复杂构建,我们需要每次都去传入所有的参数,这样极大的降低的开发的效率,其实很多属性不需要特别的去关心。

例如:现在想要去建造一个房子,普通的住户是不知道房屋的每个墙具体有多高、多厚、多宽,只需要去关心想要什么类型的房子,比如说欧洲风格的,或者中国古典建筑。

3.1 实体类房子
public class House {
    private String wallTypeName;
    private String roofTypeName;
	
    //构造方法传入建造者,并在内部实现复杂的构建过程
    public House(HouseBuilder houseBuilder) {
        this.roofTypeName=houseBuilder.getRoofType();
        this.wallTypeName=houseBuilder.getWallType();
        if("欧洲风格".equals(houseBuilder.getRoofType())){
            System.out.println("欧洲风格的房顶开始建设");
            System.out.println("复杂的房顶建造ing。。。");
        }else if("中国古典".equals(houseBuilder.getRoofType())){
            System.out.println("中国古典风格的房顶开始建设");
            System.out.println("复杂的房顶建造ing。。。");
        }
        if("木头".equals(houseBuilder.getWallType())){
            System.out.println("木头墙开始建造");
            System.out.println("复杂的墙体建造ing。。。");
        }else if("石头".equals(houseBuilder.getWallType())){
            System.out.println("石头墙开始建造");
            System.out.println("复杂的墙体建造ing。。。");
        }
        System.out.println("房子建成了");
    }

    public String getWallTypeName() {
        return wallTypeName;
    }

    public void setWallTypeName(String wallTypeName) {
        this.wallTypeName = wallTypeName;
    }

    public String getRoofTypeName() {
        return roofTypeName;
    }

    public void setRoofTypeName(String roofTypeName) {
        this.roofTypeName = roofTypeName;
    }
}
3.2 建造者
public class HouseBuilder {
    private String wallType;
    private String roofType;
    public House build(){
        return new House(this);
    }

    public String getWallType() {return wallType;}

    public void setWallType(String wallType) {this.wallType = wallType;}

    public String getRoofType() {return roofType;}

    public void setRoofType(String roofType) {this.roofType = roofType;}
    @Override
    public String toString() {
        return "HouseBuilder{" +
                "wallType='" + wallType + '\'' +
                ", roofType='" + roofType + '\'' +
                '}';
    }
}

3.3 测试
public class TestBuilder {
    public static void main(String[] args) {
        HouseBuilder houseBuilder=new HouseBuilder();
        //用户需求为欧洲风格的石头墙的房子
        houseBuilder.setRoofType("欧洲风格");
        houseBuilder.setWallType("石头");
        House house=houseBuilder.build();
        System.out.println("房顶类型为:"+house.getRoofTypeName());
        System.out.println("墙体类型为:"+house.getWallTypeName());
    }
}
3.4 结果

ss TestBuilder {
public static void main(String[] args) {
HouseBuilder houseBuilder=new HouseBuilder();
//用户需求为欧洲风格的石头墙的房子
houseBuilder.setRoofType(“欧洲风格”);
houseBuilder.setWallType(“石头”);
House house=houseBuilder.build();
System.out.println(“房顶类型为:”+house.getRoofTypeName());
System.out.println(“墙体类型为:”+house.getWallTypeName());
}
}

3.4 结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个小白QAQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值