美文网首页
简单工厂,工厂方法,抽象工厂

简单工厂,工厂方法,抽象工厂

作者: LikeWhoWho | 来源:发表于2018-09-19 08:23 被阅读0次

    简单工厂,工厂方法,抽象工厂这三个是什么玩意?工厂都有新类型了?非也,非也。这是软件设计中的设计模式。何为设计模式?模式简言之就像数学中的公式,就是程序员们在处理复杂业务的过程中发现的一套简易编码的规律。面向对象语言中生成对象的方式大多是直接使用new关键字生成对象,这在一般情况下完全可以。在业务需求经常改变的情景中,如果需要删除或添加类的话,直接去new对象或其他行为会造成客户端代码的修改。比如试卷的题目类,题目又分为单选题,多选题,填空题,问答题等。我们要生成一张试卷的话,就要分别去new单选题,多选题,填空题,问答题。

    class SingleTopic implements Serializable{
    }
    class MuiltiTopic implements Serializable{
    }
    class GapFillTopic implements Serializable{
    }
    class QuestionTopic implements Serializable{
    }
    

    客户代码:

    SingleTopic  singleTopic  = new SingleTopic ();
    MuiltiTopic muiltiTopic = new MuiltiTopic();
    GapFillTopic gapFillTopic = new GapFillTopic ();
    QuestionTopic questionTopic = new QuestionTopic ();
    

    现在产品说增加一个作文题。那我们需要新建一个作文题类,然后在客户代码添加一行new代码。

    class EssayTopic implements Serializable{
    }
    EssayTopic essayTopic = new EssayTopic ();
    

    后面产品说把试卷分为客观题和主观题两种。这时需要删除已写的类并新增类。

    class ObjectTopic implements Serializable{
    }
    class SubjectTopic implements Serializable{
    }
    SubjectTopic subjectTopic = new SubjectTopic ();
    ObjectTopic objectTopic = new ObjectTopic ();
    

    这是可以的,但是可扩展性太差了,而且在不可预知的情形下,代码维护成本高。

    面对以上需求的变化,先用简单工厂来试一下水。
    新建试题的父类:

    class Topic implements Serializable{
    }
    

    一开始的四个类:

    class SingleTopic extends Topic{
    }
    class MuiltiTopic extends Topic{
    }
    class GapFillTopic extends Topic{
    }
    class QuestionTopic extends Topic{
    }
    

    简单工厂类:

    class SimpleFactory{
        public static Topic getTopic(String type){
            if("Single".equals(type)){
                return new SingleTopic();
            }else if("Muilti".equals(type)){
                return new MuiltiTopic();
            }else if(" GapFill".equals(type)){
                return new GapFillTopic();
            }else if(" Question".equals(type)){
                return new QuestionTopic();
            }
        }
    }
    

    客户代码:

    Topic singleTopic = SimpleFactory.getTopic("Single");
    Topic muiltiTopic = SimpleFactory.getTopic("Muilti");
    Topic gapFillTopic = SimpleFactory.getTopic("GapFill");
    Topic questionTopic = SimpleFactory.getTopic("Question");
    

    ok,第一个需求满足了,现在产品说要新增一个作文题。

    class EssayTopic extends Topic{
    }
    

    这时需要修改简单工厂类啊,这是个类似工具类的角色,现在要去修改它,修改之后这个类所涉及的范围都要重新测试的啊。代价不小哦。
    简单工厂类:

    class SimpleFactory{
        public static Topic getTopic(String type){
            if("Single".equals(type)){
                return new SingleTopic();
            }else if("Muilti".equals(type)){
                return new MuiltiTopic();
            }else if(" GapFill".equals(type)){
                return new GapFillTopic();
            }else if(" Question".equals(type)){
                return new QuestionTopic();
            }else if(" Essay".equals(type)){
                            return new EssayTopic ();
                    }
        }
    }
    

    客户代码:

    Topic singleTopic = SimpleFactory.getTopic("Single");
    Topic muiltiTopic = SimpleFactory.getTopic("Muilti");
    Topic gapFillTopic = SimpleFactory.getTopic("GapFill");
    Topic questionTopic = SimpleFactory.getTopic("Question");
    Topic essayTopic = SimpleFactory.getTopic("Essay");
    

    现在要改为客观题和主观题了。代码又要删又要改了。

    class ObjectTopic extends Topic{
    }
    class SubjectTopic extends Topic{
    }
    

    简单工厂类:

    class SimpleFactory{
        public static Topic getTopic(String type){
            if("Object".equals(type)){
                return new ObjectTopic ();
            }else if("Subject".equals(type)){
                return new SubjectTopic ();
            }
        }
    }
    

    客户代码:

    Topic objectTopic = SimpleFactory.getTopic("Object");
    Topic subjectTopic = SimpleFactory.getTopic("Subject");
    

    这一圈下来,感觉咋样?累不?反正我感觉挺麻烦的。

    工厂方法模式来试试吧。
    类不变,把简单工厂类改为如下:

    abstract class FactoryMethod {
        abstract Topic creator();
    }
    class SingleFactory extends FactoryMethod {
        @Override
        Topic creator() {
            return new SingleTopic();
        }
    }
    class MuiltiFactory extends FactoryMethod {
        @Override
        Topic creator() {
            return new MuiltiTopic();
        }
    }
    class GapFillFactory extends FactoryMethod {
        @Override
        Topic creator() {
            return new GapFillTopic();
        }
    }
    class QuestionFactory extends FactoryMethod {
        @Override
        Topic creator() {
            return new QuestionTopic();
        }
    }
    

    客户代码:

    FactoryMethod singleFactory = new SingleFactory ();
    Topic single= singleFactory.creator();
    FactoryMethod muiltiFactory = new MuiltiFactory ();
    Topic muilti= muiltiFactory.creator();
    FactoryMethod gapFillFactory = new GapFillFactory ();
    Topic gapFill= gapFillFactory .creator();
    FactoryMethod questionFactory = new QuestionFactory ();
    Topic question= questionFactory.creator();
    

    现在新增一个作文题。只需添加一个EssayFactory类即可,不用修改其他代码。

    class EssayFactory extends FactoryMethod {
        @Override
        Topic creator() {
            return new EssayTopic();
        }
    }
    

    客户代码:

    FactoryMethod essayFactory = new EssayFactory ();
    Topic essay= essayFactory.creator();
    

    改为客观题和主观题。

    class ObjectFactory extends FactoryMethod {
        @Override
        Topic creator() {
            return new ObjectTopic();
        }
    }
    class SubjectFactory extends FactoryMethod {
        @Override
        Topic creator() {
            return new SubjectTopic();
        }
    }
    

    客户代码:

    FactoryMethod objectFactory = new ObjectFactory ();
    Topic object= objectFactory.creator();
    FactoryMethod subjectFactory = new ObjectFactory ();
    Topic subject= subjectFactory.creator();
    

    是不是忽然间发现只需要添加代码就行了,虽然代码看起来有点多。修改起来很方便,测试也很清晰,只需要测试新加的几个类就行,其他代码不影响。

    抽象工厂模式仅仅这几个类还不够,需要添加跟试题一起捆绑的元素,比如试题的用户答案、正确答案等。

    interface Answer implements Serializable{
    }
    

    答案对应一开始的四个类:

    class SingleAnswer implements  Answer {
    }
    class MuiltiAnswer implements Answer {
    }
    class GapFillAnswer implements Answer {
    }
    class QuestionAnswer implements Answer {
    }
    

    抽象工厂:

    interface TopicFactory {
        Answer createAnswer();
            Topic createTopic();
    }
    class SingleTopicFactory implements TopicFactory {
        @Override
        public Answer createAnswer() {
            return new SingleAnswer();
        }
        @Override
        public Topic createTopic() {
            return new SingleTopic();
        }
    }
    class MuiltiTopicFactory implements TopicFactory {
        @Override
        public Answer createAnswer() {
            return new MuiltiAnswer();
        }
        @Override
        public Topic createTopic() {
            return new MuiltiTopic();
        }
    }
    class GapFillTopicFactory implements TopicFactory {
        @Override
        public Answer createAnswer() {
            return new GapFillAnswer();
        }
        @Override
        public Topic createTopic() {
            return new GapFillTopic();
        }
    }
    class QuestionTopicFactory implements TopicFactory {
        @Override
        public Answer createAnswer() {
            return new QuestionAnswer();
        }
        @Override
        public Topic createTopic() {
            return new QuestionTopic();
        }
    }
    

    客户代码:

    TopicFactory singleTopicFactory = new SingleTopicFactory ();
    Answer singleAnswer = singleTopicFactory.createAnswer();
    Topic singleTopic = singleTopicFactory.createTopic();
    TopicFactory muiltiTopicFactory = new MuiltiTopicFactory ();
    Answer muiltiAnswer = muiltiTopicFactory.createAnswer();
    Topic muiltiTopic = muiltiTopicFactory.createTopic();
    TopicFactory gapFillTopicFactory= new GapFillTopicFactory ();
    Answer gapFillAnswer = gapFillTopicFactory.createAnswer();
    Topic gapFillTopic = gapFillTopicFactory.createTopic();
    TopicFactory questionTopicFactory= new QuestionTopicFactory ();
    Answer questionAnswer = questionTopicFactory.createAnswer();
    Topic questionTopic = questionTopicFactory.createTopic();
    

    增加一个作文题和作文答案:

    class EssayTopic extends Topic{
    }
    class EssayAnswer implements Answer {
    }
    class EssayTopicFactory implements TopicFactory {
        @Override
        public Answer createAnswer() {
            return new EssayAnswer();
        }
        @Override
        public Topic createTopic() {
            return new EssayTopic();
        }
    }
    

    客户代码:

    TopicFactory essayTopicFactory= new EssayTopicFactory ();
    Answer essayAnswer = essayTopicFactory.createAnswer();
    Topic essayTopic = essayTopicFactory.createTopic();
    

    改为客观题和主观题,还有客观答案和主观答案:

    class SubjectTopic extends Topic{
    }
    class SubjectAnswer implements Answer {
    }
    class SubjectTopicFactory implements TopicFactory {
        @Override
        public Answer createAnswer() {
            return new SubjectAnswer();
        }
        @Override
        public Topic createTopic() {
            return new SubjectTopic();
        }
    }
    class ObjectTopic extends Topic{
    }
    class ObjectAnswer implements Answer {
    }
    class ObjectTopicFactory implements TopicFactory {
        @Override
        public Answer createAnswer() {
            return new ObjectAnswer();
        }
        @Override
        public Topic createTopic() {
            return new ObjectTopic();
        }
    }
    

    客户代码:

    TopicFactory subjectTopicFactory= new SubjectTopicFactory ();
    Answer subjectAnswer = subjectTopicFactory.createAnswer();
    Topic subjectTopic = subjectTopicFactory.createTopic();
    TopicFactory objectTopicFactory= new ObjectTopicFactory ();
    Answer objectAnswer = objectTopicFactory.createAnswer();
    Topic objectTopic = objectTopicFactory.createTopic();
    

    其实回头来看看抽象工厂模式和工厂方法模式是差不多的,只不过抽象工厂封装的是一套类,工厂方法是一个类而已。简单工厂其实就是调用静态方法来生成对象,可扩展性差,来回的修改,不过调用方式简单,只需传个参数即可获取对象。工厂方法模式和抽象工厂模式就是代码比较多,但是可扩展性强些,需求改动只需增加或删除一个类。

    相关文章

      网友评论

          本文标题:简单工厂,工厂方法,抽象工厂

          本文链接:https://www.haomeiwen.com/subject/fazpnftx.html