23种经典设计模式-工厂模式(详解)

经典设计模式是前辈们在实际应用中总结出来的经验,之所以被设定为标准并推广,肯定有其道理。其中很多开发人员只注重于业务的实现,开发中并不注重代码设计。

我见过开发3年左右的程序员,代码中全都是if else,在特定的场景下使用设计模式会使我们的代码更有利于维护和扩展,同时也不容易出错,在一定程度上也能更加理解面向对象的概念。

工厂模式在开发中是比较常用的设计模式,我们一般创建对象用 new 关键字,工厂模式就是替我们创建了对象。

像一些常见的工具类Calendar.getInstance() , LoggerFactory.getLogger(this.getClass()) 查看其源码都用到了工厂方法。

工厂模式分为简单工厂模式、工厂方法模式和抽象工厂模式,都属于创建型模式。

简单工厂模式

简单工厂模式(Simple Factory Pattern):是指由一个工厂对象决定创建出哪一种产品类的实例。

适用场景:

工厂类负责创建的对象较少。

客户端只需要传入工厂类的参数,对于如何创建对象的逻辑不需要关心。

优点:

只需传入一个正确的参数,就可以获取你所需要的对象无须知道其创建的细节。

缺点 :

工厂类的职责相对过重,增加新的产品时需要修改工厂类的判断逻辑,违背开闭原则。

不易于扩展过于复杂的产品结构。

例:现在有几款电脑,联想、苹果、华硕等。

1、先定义一个电脑标准

public interface IComputer {
    /**
     * 价格
    */
    void getPrice();
}
2、创建实现类,苹果电脑和联想电脑

public class IphoneComputer implements IComputer {
    @Override
    public void getPrice() {
        System.out.println("苹果电脑");
    }
}

public class LenovoComputer implements IComputer{
    @Override
    public void getPrice() {
        System.out.println("联想电脑");
    }
}
3、不用工厂实现
 @org.junit.Test
  public void test1(){
      IComputer lenovoComputer = new LenovoComputer();
      lenovoComputer.getPrice();
      IComputer iphoneComputer = new IphoneComputer();
      iphoneComputer.getPrice();
  }

可见这种方式如果实现类越来越多,代码就会越来越臃肿。

但是如果我们可以把创建对象的细节隐藏起来,也就是交给工厂去实现,代码就会非常清爽了。

4、简单工厂模式实现,传入对应参数生成对象。

工厂类


public class SimpleComputerFactory {
    public static IComputer createComputer(String type){
        if ("Lenovo".equals(type)){
            return new LenovoComputer();
        }
        if ("Iphone".equals(type)){
            return new IphoneComputer();
        }
        return null;
    }
 }

看下类图

调用
 


//使用工厂
   @org.junit.Test
    public void test2(){
        IComputer iComputer = SimpleComputerFactory.createComputer("Lenovo");
        iComputer.getPrice();
    }

这种工厂实现方式有个问题,就是产品越来越多的时候,需要频繁的修改工厂方法,不符合开闭原则,我们可以利用反射技术进行优化。

public static IComputer createComputer(Class<? extends IComputer> clazz){
        try{
            if (null!=clazz){
                return clazz.newInstance();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

看下类图

再次调用


//优化后的工厂
    @org.junit.Test
    public void test3(){
        IComputer iComputer = SimpleComputerFactory.createComputer(IphoneComputer.class);
        iComputer.getPrice();
    }

工厂方法模式

在简单工厂中,随着产品链的丰富,如果每个产品创建的逻辑又有所不同,那么工厂的职责会变得越来越多,有点像万能工厂,不利于维护。

这种情况下,将职责拆分,专人干专事,也符合单一职责原则。分为联想工厂和苹果工厂。

工厂方法模式(Fatory Method Pattern)是指定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。主要解决产品扩展的问题。

使用场景:

创建类需要大量重复代码

1、定义抽象工厂
public interface IComputerFactory {
    /**
     * 生产电脑
     * @return
     */
    IComputer create();
}
2、实现联想工厂

public class LenovoComputerFactory implements IComputerFactory{
    @Override
    public IComputer create() {
        return new LenovoComputer();
    }
}
3、实现苹果工厂

public class IphoneComputerFactory implements IComputerFactory{
    @Override
    public IComputer create() {
        return new IphoneComputer();
    }
}
4、测试

//工厂方法
    @org.junit.Test
    public void test4(){
        IComputerFactory lenovoComputerFactory = new LenovoComputerFactory();
        lenovoComputerFactory.create().getPrice();
        IComputerFactory iphoneComputerFactory = new IphoneComputerFactory();
        iphoneComputerFactory.create().getPrice();

    }

抽象工厂模式

抽象工厂模式(Abastract Factory Pattern)是指提供一个创建一系列相关或相互依赖对象的接口,无须指定他们具体的类。

客户端(应用层)不依赖于产品类实例如何被创建、实现等细节,强调的是一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码。需要提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。

首先能称为组证明不是一个单独的个体。举网上一个例子来说明产品组的概念。美的电器和格力电器,我们都知道这两个品牌都不是只生产单一的产品。美的电器生产洗衣机、空调、电风扇,那么同样格力也生产洗衣机、空调、电风扇。这里洗衣机、空调、电风扇就可以成为一个产品组。

本篇中的例子,具体结构如下:

1、价格和质量接口


public interface IPrice {
    /**
     * 价格
    */
    void getPrice();
}

public interface IQuality {
    /**
     * 质量
     */
    void getQuality();
}

2、联想产品组

public class LenovoPrice implements IPrice{
    @Override
    public void getPrice() {
        System.out.println("联想价格");
    }
}

public class LenovoQuality implements IQuality{
    @Override
    public void getQuality() {
        System.out.println("联想质量");
    }
}

3、苹果产品组


public class IphonePrice implements IPrice{
    @Override
    public void getPrice() {
        System.out.println("苹果价格");
    }
}

public class IphoneQuality implements IQuality{
    @Override
    public void getQuality() {
        System.out.println("苹果质量");
    }
}

4、抽象工厂

public interface IComputerFactoryNew {
    /**
     * 价格
     * @return com.zhkj.publicservice.utils.factorytest.IPrice
    */
    IPrice createPrice();
    /**
     * 质量
     * @return com.zhkj.publicservice.utils.factorytest.IQuality
    */
    IQuality createQuality();
}

5、联想工厂实现


public class LenovoComputerFactoryNew implements IComputerFactoryNew {

    @Override
    public IPrice createPrice() {
        return new LenovoPrice();
    }

    @Override
    public IQuality createQuality() {
        return new IphoneQuality();
    }
}

6、苹果工厂实现


public class IphoneComputerFactoryNew implements IComputerFactoryNew{
    @Override
    public IPrice createPrice() {
        return new IphonePrice();
    }

    @Override
    public IQuality createQuality() {
        return new IphoneQuality();
    }
}

7、测试


//抽象工厂方法
    @org.junit.Test
    public void test5(){
        IphoneComputerFactoryNew iphoneComputerFactoryNew = new IphoneComputerFactoryNew();
        iphoneComputerFactoryNew.createPrice().getPrice();
        iphoneComputerFactoryNew.createQuality().getQuality();

    }

  • 24
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

missterzy

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

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

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

打赏作者

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

抵扣说明:

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

余额充值