Java设计模式——工厂模式与抽象工厂模式

Hello大家晚上好,我是阿Q,好久不见,甚为想念(窃喜)。最近一段时间一直在参与安卓项目的开发(已忙成狗),也没能抽出时间来继续为大家总结设计模式的知识,在这里Say sorry了。由于好久没有写安卓方面的东西了,所以最近一段时间写起代码来事倍功半,踩了N多坑,被虐成Dog了。我最近有一个想法,就是想将之前学过的安卓知识再拾起来,以后在讲解java知识的同时也穿插着总结一下安卓的知识,也不知道大家感不感兴趣。如果大家想学习安卓或者有什么技术交流的可以在公众号后台给阿Q留言,阿Q视情况不定期更新安卓。好了,今晚回来的比较早,就抽时间讲一下工厂模式与抽象工厂设计模式吧。

简单工厂模式

首先呢,我们先来了解一下简单工厂模式。其实简单工厂模式并不是一个真正的设计模式,而是一种编程习惯。既然是一种习惯,就说明它有可取之处。所谓简单工厂模式,就是定义一个工厂类,将实例化对象的操作放在该工厂中去执行,当客户端调用的时候只需要将参数传入工厂就可得到该实体类。接下来阿Q就用一个小Demo来给大家做更详细的讲解。

一、定义一个抽象的接口

//定义课程接口
public interface Course {
    void desc();
}

二、声明实体类来实现该接口

//语文课类
public class Chinese implements Course{

    @Override
    public void desc() {
        System.out.println("这是语文课");
    }

}

//数学课类
public class Math implements Course{

    @Override
    public void desc() {
        System.out.println("这是数学课");
    }

}

//英语课类
public class English implements Course{

    @Override
    public void desc() {
        System.out.println("这是英语课");
    }

}

三、定义一个工厂类来管理上边声明的实体类

//定义工厂类
public class MyFactory {
    
    public static Course selectCourse(String type) {
        
        Course course = null;
        
        switch (type) {
            case "chinese":
                course = new Chinese();
                break;
    
            case "math":
                course = new Math();
                break;
                
            case "english":
                course = new English();
                break;
        }
        return course;
    }
}

四、客户端调用

public class TestDemo {
    
    public static void main(String[] args) {
        
        Course course1 = MyFactory.selectCourse("chinese");
        Course course2 = MyFactory.selectCourse("math");
        Course course3 = MyFactory.selectCourse("english");
        course1.desc();
        course2.desc();
        course3.desc();
    }

}

执行结果

1.png

简单设计模式的优点:对于客户端来说,去除了具体的类的依赖;无需提供具体的类名,只需要调用工厂类传入相应的参数就可以得到相应的实体类;

简单设计模式的缺点:就是每需要增加一个实体类,就需要去修改工厂类中的方法,可扩展性差;不同的产品需要不同额外参数的时候不支持;耦合性高,违反了开—闭原则。

工厂模式(Factory Pattern)

工厂模式是简单工厂的仅一步深化,在工厂模式中,我们不再提供一个统一的工厂类来创建所有的对象,而是针对不同的对象提供不同的工厂,也就是说每个对象都有一个与之对应的工厂。这样说有点抽象,那我们就用“实力”说话。

一、定义一个抽象接口

//课程接口
public interface Course {
    //课程描述
    void desc();
}

二、定义实体类实现抽象接口

//语文课实体类
public class Chinese implements Course{

    @Override
    public void desc() {
        System.out.println("这是语文课");
    }

}

//数学课实体类
public class Math implements Course{

    @Override
    public void desc() {
        System.out.println("这是数学课");
    }

}

三、定义工厂类

//定义工厂基类
public interface BaseFactory {
    Course getCourse();
}

四、定义各个实体类对应的工厂类

//语文课工厂类
public class ChineseFactory implements BaseFactory{

    @Override
    public Course getCourse() {
        return new Chinese();
    }

}
//数学课工厂类
public class MathFactory implements BaseFactory{

    @Override
    public Course getCourse() {
        return new Math();
    }

}

五、客户端调用

public class TestDemo {
    
    public static void main(String[] args) {
        
        try {
            //使用反射机制实例化工厂对象,因为字符串是可以通过变量改变的
            BaseFactory chineseFactory = (BaseFactory)Class.forName("com.itcast.ChineseFactory").newInstance();
            BaseFactory mathFactory=(BaseFactory)Class.forName("com.itcast.MathFactory").newInstance();
           
            //也可以用
            //BaseFactory chineseFactory = new ChineseFactory();
            //BaseFactory mathFactory = new MathFactory();
            Course chineseCourse = chineseFactory.getCourse();
            Course mathCourse = mathFactory.getCourse();
            chineseCourse.desc();
            mathCourse.desc();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }

}

执行结果:

2.png

工厂模式的优点:工厂方法把简单工厂的内部逻辑判断转移到了客户端代码来进行,克服了简单工厂模式违背的开—闭原则;保持了封装对象创建过程的优点;扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以;屏蔽产品的具体实现,调用者只关心产品的接口。

工厂模式的缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。

抽象工厂模式(Abstract Factory Pattern)

抽象工厂模式是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。接下来同样举例说明。

一、定义实体类

//汽车座椅
public class Sofa {
    //颜色
    private String color;
    //舒适度
    private String soft;
    
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    public String getSoft() {
        return soft;
    }
    public void setSoft(String soft) {
        this.soft = soft;
    }
}

//汽车车轮
public class Wheel {
    //半径
    private String radiu;
    //大小
    private String size;
    
    public String getRadiu() {
        return radiu;
    }
    public void setRadiu(String radiu) {
        this.radiu = radiu;
    }
    public String getSize() {
        return size;
    }
    public void setSize(String size) {
        this.size = size;
    }

}

二、定义两个接口

//汽车座椅
public interface ISofa {
    //改变座椅颜色
    void changeColor();
    //改变座椅舒适度
    void changeSoft();
}

//汽车车轮
public interface IWheel {
    //改变大小
    void changeSize();
    //改变半径
    void changeRadius();
}

三、定义不同的实体类分别实现两接口

//本田汽车的座椅
public class BenSofa implements ISofa {

    @Override
    public void changeColor() {
        System.out.println("本田车变为蓝色了");
    }

    @Override
    public void changeSoft() {
        System.out.println("本田车变舒服了");
    }

}

//丰田汽车的座椅
public class FengSofa implements ISofa{

    @Override
    public void changeColor() {
        System.out.println("丰田车变为红色了");
    }

    @Override
    public void changeSoft() {
        System.out.println("丰田车变不舒服了");
    }

}

//本田汽车的车轮
public class BenWheel implements IWheel{

    @Override
    public void changeSize() {
        System.out.println("本田车轮子变大了");
    }

    @Override
    public void changeRadius() {
        System.out.println("本田车轮子半径变大了");
    }

}

//丰田汽车的车轮
public class FengWheel implements IWheel{
    
    @Override
    public void changeSize() {
        System.out.println("丰田车轮子变小了");
    }

    @Override
    public void changeRadius() {
        System.out.println("丰田车轮子半径变小了");
    }

}

四、定义抽象工厂类

//汽车工厂类
public interface CarFactory {
    //获取座椅对象
    ISofa getSofa();
    //获取车轮对象
    IWheel getWheel();
}

五、定义工厂实现类

//本田汽车
public class BenCarFactory implements CarFactory{

    @Override
    public ISofa getSofa() {
        return new BenSofa();
    }

    @Override
    public IWheel getWheel() {
        return new BenWheel();
    }
}

//丰田汽车
public class FengCarFactory implements CarFactory{

    @Override
    public ISofa getSofa() {
        return new FengSofa();
    }

    @Override
    public IWheel getWheel() {
        return new FengWheel();
    }

}

六、客户端调用

public class DemoTest {
    
    public static void main(String[] args) {
        CarFactory benCar = new BenCarFactory();
        ISofa sofa = benCar.getSofa();
        sofa.changeColor();
        sofa.changeSoft();
    }

}

执行结果:

3.png

抽象工厂模式优点: 抽象工厂模式最大的好处是易于交换产品系列,由于具体工厂类在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。不管是任何人的设计都无法去完全防止需求的更改,或者项目的维护,那么我们的理想便是让改动变得最小、最容易。抽象工厂模式的另一个好处就是它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操作实例,产品实现类的具体类名也被具体的工厂实现类分离,不会出现在客户端代码中。

抽象工厂模式缺点:客户端程序肯定不止一个,每次都需要声明,如果有100个调用CarFactory的类,就需要更改100次CarFactory benCar = new BenCarFactory();太繁琐。

好了今天就先说到这了,想了解更多学习知识,请关注微信公众号“阿Q说”,获取更多学习资料吧!你也可以后台留言说出你的疑惑,阿Q将会在后期的文章中为你解答。每天学习一点点,每天进步一点点。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351

推荐阅读更多精彩内容