设计模式阶段一-单例、工厂相关解析

很久没有写技术博客了,最近太忙,再加上家里面的杂事儿太多,导致最近整个人都是不在状态,不过不管怎么说,该更新的博客,还是需要更新的,上一篇吐槽了最近项目重构优化的事情,也说了用了一些相关的设计模式,所以呢,我就是打算开始更新一部分我所熟悉的设计模式。

设计模式的更新,我打算分成五个阶段,第一个阶段呢,我打算先更新常用的单例、工厂、模板、代理这几种设计模式,因为这几种设计模式我相对来说比较熟,而且真正项目中使用过的,将几种设计模式讲过之后,我就是讲一些相关设计模式在常用框架或者工具类中的使用,加深我们的印象。

讲解设计模式呢,我就不关公面前耍大刀了,我打算完全按照《设计模式之禅》上面的来,这本书是我入门设计模式的书,买了好几年,但是就零零散散翻过一部分,之前代码重构的时候看过一丢丢,但是还是没有看完,这次就是趁着写博客的机会,把它从头到尾搞一遍吧。

好了,废话不多说,咱们现在开始第一阶段单例、工厂设计模式的讲解。

单例

单例的实现,现在网上相关的博客,也是非常多,所以我这边呢,也就是给出一个最简单的一种,其他的不多说,直接上代码吧,我想大家肯定是能够看懂的:
单例类Logger :

/***
 * @desc 单例
 * @author Aby
 * @date 2020/07/25
 */
public class Logger {
    private static final Logger logger = new Logger();

    private Logger() {
    }

    public static Logger getInstance() {
        return logger;
    }
}

测试类App :

/***
 * @desc 测试单例
 * @author Aby
 * @date 2020/07/25
 */
public class App {
    public static void main(String[] args) {
        Logger logger = Logger.getInstance();
        Logger logger2 = Logger.getInstance();
        System.out.println(logger == logger2);
    }
}

好了,单例的代码已经写完了,其实就是私有了一个无参构造器,然后在类初始化的时候,就进行创建,并且提供一个静态方法,获取创建的对象即可,因为只初始化一次,所以是能够保证是单例的。

不过上面的这种写法,其实真正的想破解还是有方法的,不过那些不在咱们的考虑范围之内。

我提供的这个单例只是最简单最基础的一种,现在其实网上有各种各样的单例写法,大家有空也可以看看,对于工作的话,大多数时候其实也够用了,不过面试的时候可能会考你各种单例的实现模式吧,这一点儿需要关注一下。

好了,单例的讲完了,接下来咱们开始讲解一下相关的工厂模式。

工厂模式

工厂模式按照我们常用的,一般来说是分成普通工厂和抽象工厂,咱们先从普通工厂模式进行讲解。

普通工厂模式

假如说现在一个玩具公司,接到了一批玩具的订单,这批订单呢,总共是要生产两种玩具,一种是猴子,一种是小狗,其中呀,猴子是吱吱叫,小狗是汪汪叫,那么按照我们的普通工厂模式的话,定义相关的类就是如下的形式:
首先,玩具接口类IToy:

/***
 * @desc 玩具类接口
 * @author Aby
 * @date 2020/07/25
 */
public interface IToy {
    /***
     * 玩具叫
     */
    void getCry();
}

猴子的实现类MonkeyToy:

/***
 * @desc 猴子的实现类
 * @author Aby
 * @date 2020/07/25
 */
public class MonkeyToy implements IToy {
    @Override
    public void getCry() {
        System.out.println("猴子吱吱叫");
    }
}

小狗的实现类DogToy:

/***
 * @desc 小狗的实现类
 * @author Aby
 * @date 2020/07/25
 */
public class DogToy implements IToy {
    @Override
    public void getCry() {
        System.out.println("小狗汪汪叫");
    }
}

工厂接口AbstractToyFactory:

/***
 * @desc 工厂生成
 * @author Aby
 * @date 2020/07/25
 */
public abstract class AbstractToyFactory {
    /**
     * @param c   实现了T泛型接口的子类
     * @param <T> 泛型限制
     * @return 返回对应的实现
     */
    public abstract <T extends IToy> T createToy(Class<T> c);
}

工厂实现类ToyFactory:

/***
 * @desc 具体工厂
 * @author Aby
 * @date 2020/07/25
 */
public class ToyFactory extends AbstractToyFactory {
    @Override
    public <T extends IToy> T createToy(Class<T> c) {
        //定义一个玩具
        IToy toy = null;
        try {
            //产生一个玩具
            toy = (T) Class.forName(c.getName()).newInstance();
        } catch (Exception e) {
            System.out.println("生成玩具失败!");
        }
        return (T) toy;
    }
}

测试类CommonApp:

public class CommonApp {
    public static void main(String[] args) {
        AbstractToyFactory factory = new ToyFactory();
        MonkeyToy monkeyToy = factory.createToy(MonkeyToy.class);
        monkeyToy.getCry();

        DogToy dogToy = factory.createToy(DogToy.class);
        dogToy.getCry();
    }
}

好了,执行测试类,能够打印出对应的玩具的叫声,咱们的普通工厂也实现完成了。
其实普通工厂模式,咱们基本上写代码用到的很多,特别是产品类的实现,就像我最近做的库存一样,都是属于备件,但是细分的话,又是不少种,这次优化代码的时候,就是用到了这一点儿。

抽象工厂模式

假如说玩具厂猴子玩具和小狗玩具,生产了一半了,因为产品做工质量非常高,现在公司又追加了一笔订单,还是生产猴子玩具和小狗玩具,但是呀,这一次的玩具要求具备不同的颜色,普通工厂模式的时候,因为没管颜色,都是统一的配色,但是现在需要有红色和黄色的了,那么按照上面的普通工厂模式的时候,我们肯定是需要在IToy接口新增对应的方法,然后修改对应的实现类,然后将相关联的都进行修改。

这种方式可以吗?其实是可以的,完成我们的目标完全是没什么问题的,但是假如说之后玩具又追加了其他的一系列的唱、跳、Rap的功能,我们还这么改吗?伴随着项目的运行,这种改动涉及的范围越来越广,也越来越没有保障,所以才出现了抽象工厂模式,具体的实现如下所示:
首先,玩具接口类IToy改造如下:

/***
 * @desc 玩具类接口
 * @author Aby
 * @date 2020/07/25
 */
public interface IToy {
    /***
     * 玩具叫
     */
    void getCry();
    
    /***
     * 玩具的颜色
     */
    void getColor();
}

猴子类MonkeyToy改造如下:

/***
 * @desc 猴子的实现类
 * @author Aby
 * @date 2020/07/25
 */
public abstract class MonkeyToy implements IToy {
    @Override
    public void getCry() {
        System.out.println("猴子吱吱叫");
    }
}

小狗类DogToy 改造如下:

/***
 * @desc 小狗的实现类
 * @author Aby
 * @date 2020/07/25
 */
public abstract class DogToy implements IToy {
    @Override
    public void getCry() {
        System.out.println("小狗汪汪叫");
    }
}

工厂接口AbstractToyFactory保持不变:

/***
 * @desc 工厂生成
 * @author Aby
 * @date 2020/07/25
 */
public abstract class AbstractToyFactory {
    /**
     * @param c   实现了T泛型接口的子类
     * @param <T> 泛型限制
     * @return 返回对应的实现
     */
    public abstract <T extends IToy> T createToy(Class<T> c);
}

实现工厂类ToyFactory 保持不变:

/***
 * @desc 具体工厂
 * @author Aby
 * @date 2020/07/25
 */
public class ToyFactory extends AbstractToyFactory {
    @Override
    public <T extends IToy> T createToy(Class<T> c) {
        //定义一个玩具
        IToy toy = null;
        try {
            //产生一个玩具
            toy = (T) Class.forName(c.getName()).newInstance();
        } catch (Exception e) {
            System.out.println("生成玩具失败!");
        }
        return (T) toy;
    }
}

紧接着,我们需要创建对应的黄色猴子玩具类YellowMonkeyToy了:

/***
 * @desc 黄色猴子玩具类
 * @author Aby
 * @date 2020/07/25
 */
public class YellowMonkeyToy extends MonkeyToy {
    @Override
    public void getColor() {
        System.out.println("黄色猴子玩具");
    }
}

红色猴子玩具类RedMonkeyToy了:

/***
 * @desc 红色猴子玩具类
 * @author Aby
 * @date 2020/07/25
 */
public class RedMonkeyToy extends MonkeyToy {
    @Override
    public void getColor() {
        System.out.println("红色猴子玩具");
    }
}

然后是黄色小狗玩具类YellowDogToy:

/***
 * @desc 黄色小狗玩具类
 * @author Aby
 * @date 2020/07/25
 */
public class YellowDogToy extends DogToy {
    @Override
    public void getColor() {
        System.out.println("黄色小狗玩具");
    }
}

红色小狗玩具类RedDogToy:

/***
 * @desc 红色小狗玩具类
 * @author Aby
 * @date 2020/07/25
 */
public class RedDogToy extends DogToy {
    @Override
    public void getColor() {
        System.out.println("红色小狗玩具");
    }
}

好了,定义完成,接下来就是看看我们的测试类App了:

public class App {

    public static void main(String[] args) {
        AbstractToyFactory factory = new ToyFactory();
        MonkeyToy yellowMonkeyToy = factory.createToy(YellowMonkeyToy.class);
        yellowMonkeyToy.getColor();
        yellowMonkeyToy.getCry();

        MonkeyToy redMonkeyToy = factory.createToy(RedMonkeyToy.class);
        redMonkeyToy.getColor();
        redMonkeyToy.getCry();

        DogToy yellowDogToy = factory.createToy(YellowDogToy.class);
        yellowDogToy.getColor();
        yellowDogToy.getCry();

        DogToy redDogToy = factory.createToy(RedDogToy.class);
        redDogToy.getColor();
        redDogToy.getCry();

    }
}

好了,执行对应的测试类,我们能够看到我们成功生成出符合要求的玩具,而且不管以后要生成什么颜色的玩具,只需要新增对应的产品类就成了,相比起普通工厂模式,抽象工厂模式相比来说原有逻辑改动较小,可扩展性也相对高一点儿,在项目中应用的话,相对来说便于以后扩展。

好了,这次的设计模式就讲到这里,下一讲咱们就是开始讲讲模板和代理两种设计模式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值