设计模式-工厂模式

简单工厂

简单工厂模式又叫作静态工厂方法模式,有一个具体的工厂类,嗯可以生成多个不同的产品,属于创建型设计模式。

应用场景

对于产品种类相对较少的情况,考虑使用简单工厂模式可以很方便地创建所需产品。使用简单工厂模式的客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻辑。

简单工厂模式主要包含3个角色:

  1. 简单工厂(SimpleFactory):是简单工厂模式的核心,负责实现创建所有实例的内部逻辑。
  2. 抽象产品(IProduct):是简单工厂创建的所有对象的父类,负责描述所有实例共有的公共接口。
  3. 具体产品(ConcreteProduct):是简单工厂模式的创建目标。

package com.yab.simple;

/**
 * IProduct 简单工厂创建的所有对象的父类,负责描述所有实例共有的公共接口
 */
public interface ITea{
    //生产茶叶
    public void productionTea();
}
package com.yab.simple;

/**
 * ConcreteProduct 简单工厂模式的创建目标
 */
public class GreenTea implements ITea {
    @Override
    public void productionTea() {
        System.out.println("生产绿茶");
    }
}
package com.yab.simple;

public class RedTea implements ITea {
    @Override
    public void productionTea() {
        System.out.println("生产红茶");
    }
}

package com.yab.simple;

/**
 * SimpleFactory:是简单工厂模式的核心,负责实现创建所有实例的内部逻辑
 */
public class TeaFactory extends RedTea {
    public ITea create(String name){
        if("greenTea".equals(name)){
            return new GreenTea();
        }else if("redTea".equals(name)){
            return new RedTea();
        }else {
            return null;
        }
    }
}

package com.yab.simple;

public class Test extends TeaFactory {

    public static void main(String[] args) {
         TeaFactory teaFactory = new TeaFactory();
         teaFactory.create("greenTea").productionTea();
    }

}

到此一个简单工厂产生了。

当业务继续扩展,需要增加新种类的茶,工厂中的create()方法每次都要修改代码逻辑,不符合开闭原则。因此,可以采用反射,对简单工厂模式优化。

package com.yab.simple;

/**
 * 反射优化工厂
 */
public class TeaFactoryRef {
    public ITea createRef(String className){
        try {
            if(!(null==className || "".equals(className))){
                return (ITea) Class.forName(className).newInstance();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
package com.yab.simple;

public class TestRef {
    public static void main(String[] args) {
        TeaFactoryRef teaFactoryRef = new TeaFactoryRef();
        ITea iTea = teaFactoryRef.createRef("com.yab.simple.RedTea");
        iTea.productionTea();
    }
}

优化之后,不在需要修改TeaFactoryRef中的代码。但还是有问题,方法参数是字符串(如果输错不就坑了自己),可控性待提升,而且还需要强制转型。 

接着我们继续修改代码。

package com.yab.simple;

public class TeaFactoryLast {
    public ITea createLast(Class<? extends ITea> teaClass){
        try {
            if(null != teaClass){
                return teaClass.newInstance();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

package com.yab.simple;

public class TestLast {
    public static void main(String[] args) {
        TeaFactoryLast teaFactoryLast = new TeaFactoryLast();
        ITea iTea = teaFactoryLast.createLast(RedTea.class);
        iTea.productionTea();
    }
}

工厂方法模式

工厂方法模式又叫作多态性工厂模式,指定义一个创建对象的接口,但由实现这个接口的类来决定实例化哪个类,工厂方法把类的实例化推迟到子类中进行。

应用场景

创建对象需要大量重复的代码。

客户端不依赖产品类,实例如何被创建、实现等细节。

一个类通过其子类来指定创建哪个对象。

抽象工厂包含4个角色

抽象工厂(IFactory):工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。

具体工厂(ConcreteFactory):实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且被应用程序调用以创建产品对象。

抽象产品(IProduct):工厂方法模式所创建的对象的超类型,是产品对象的共同父类或者共同拥有的接口。

具体产品(ConcreteProduct):这个角色实现了抽象产品角色所定义的接口。

工厂方法模式

优点:

灵活性增强,对于新产品的创建,只需要写一个相应的工厂类(GreenTeaFactory 、RedTeaFactory)。

典型的解耦框架。高层模块只需要知道产品的抽象类,无需关心其他实现类,满足迪米特法则、依赖倒置原则和里氏替换原则

缺点:

类的个数过多

增加了系统的抽象性和理解难度

抽象产品只能生产一种产品

package com.yab.fun;

public interface ITea{
    //生产茶叶
    public void teaName();
}


package com.yab.fun;

/**
 * ConcreteProduct 简单工厂模式的创建目标
 */
public class GreenTea extends GreenTeaFactory implements ITea {
    @Override
    public void teaName() {
        System.out.println("生产绿茶");
    }
}


package com.yab.fun;

/**
 * 具体产品ConcreteProduct:是简单工厂模式的创建目标。
 */
public class RedTea extends RedTeaFactory implements ITea {
    @Override
    public void teaName() {
        System.out.println("生产红茶");
    }
}


package com.yab.fun;

/**
 * 抽象工厂(IFactory):工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。
 */
public interface ITeaFactory {
    com.yab.fun.ITea teaFactory();
}



package com.yab.fun;

/**
 * 具体工厂(ConcreteFactory):实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且被应用程序调用以创建产品对象。
 */
public class GreenTeaFactory implements ITeaFactory {
    @Override
    public ITea teaFactory() {
        return new GreenTea();
    }
}


package com.yab.fun;

/**
 * 具体工厂(ConcreteFactory):实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且被应用程序调用以创建产品对象。
 */
public class RedTeaFactory implements ITeaFactory {
    @Override
    public ITea teaFactory() {
        return new RedTea();
    }
}


package com.yab.fun;

public class TestFactoryFun extends RedTea {
    /**
     * 优点:
     * 灵活性增强,对于新产品的创建,只需要写一个相应的工厂类(GreenTeaFactory 、RedTeaFactory)。
     * 典型的解耦框架。高层模块只需要知道产品的抽象类,无需关心其他实现类,满足迪米特法则、依赖倒置原则和里氏替换原则
     *
     * 缺点:
     * 类的个数过多
     * 增加了系统的抽象性和理解难度
     * 抽象产品只能生产一种产品
     * @param args
     */
    public static void main(String[] args) {
        ITeaFactory iTeaFactory = new GreenTeaFactory();
        iTeaFactory.teaFactory().teaName();

        iTeaFactory = new RedTeaFactory();
        iTeaFactory.teaFactory().teaName();
    }
}

抽象工厂

抽象工厂模式适用于需要生成产品族的情景。抽象产品类内部提供了多个其他抽象产品,抽象工厂类定义了产品的创建接口,通过具体的工厂子类,就可以生产相应的产品族对象,供用户端使用。

抽象工厂包含4个角色

抽象工厂(IAbstractFactory):声明创建抽象产品对象的一个操作接口。

具体工厂(ConcreteFactory):实现创建具体产品对象的操作。

抽象产品(IAbstractProduct):为一类产品对象声明一个接口。

具体产品(ConcreteProduct):定义一个将被相应的具体工厂创建的产品对象,实现IAbstractProduct接口。

优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象工厂里加代码,又要在具体工厂的里面加代码,不符合开闭原则。

package com.yab.abstr;

public interface INote {
    void edit();
}

package com.yab.abstr;

public interface IVideo {
    void record();
}


package com.yab.abstr;

public class JavaNote implements INote {
    @Override
    public void edit() {
        System.out.println("编写java笔记");
    }
}


package com.yab.abstr;

public class JavaVideo implements IVideo {
    @Override
    public void record() {
        System.out.println("录制java视频");
    }
}


package com.yab.abstr;

public class PythonNote implements INote {
    @Override
    public void edit() {
        System.out.println("编写python笔记");
    }
}

package com.yab.abstr;

public class PythonVideo implements IVideo {
    @Override
    public void record() {
        System.out.println("录制python视频");
    }
}


package com.yab.abstr;

public abstract class CourseFactory {
    public void init(){
        System.out.println("初始化基础数据");
    }
    protected abstract INote createNote();
    protected abstract IVideo createVideo();
}


package com.yab.abstr;

public class JavaCourseFactory extends CourseFactory {
    @Override
    protected INote createNote() {
        return new JavaNote();
    }

    @Override
    protected IVideo createVideo() {
        return new JavaVideo();
    }
}



package com.yab.abstr;

public class PythonCourseFactory extends CourseFactory {
    @Override
    protected INote createNote() {
        return new PythonNote();
    }

    @Override
    protected IVideo createVideo() {
        return new PythonVideo();
    }
}


package com.yab.abstr;

public class TestFactory {
    public static void main(String[] args) {
        CourseFactory courseFactory = new JavaCourseFactory();
        courseFactory.createNote().edit();
        courseFactory.createVideo().record();
    }
}




 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值