Java设计模式(二)--工厂设计模式

来源:互联网 发布:软件评测师真题 编辑:程序博客网 时间:2024/06/05 20:14

设计模式的分类

总体来说设计模式分为三大类:

创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。


设计模式的六大原则

1、开闭原则(Open Close Principle)

开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。

2、里氏代换原则(Liskov Substitution Principle)

里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。—— From Baidu 百科

3、依赖倒转原则(Dependence Inversion Principle)

这个是开闭原则的基础,具体内容:真对接口编程,依赖于抽象而不依赖于具体。

4、接口隔离原则(Interface Segregation Principle)

这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。所以上文中多次出现:降低依赖,降低耦合。

5、迪米特法则(最少知道原则)(Demeter Principle)

为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。

6、合成复用原则(Composite Reuse Principle)

原则是尽量使用合成/聚合的方式,而不是使用继承。


一、创建型模式

1、简单工厂模式

一个工厂 可以生产很多的产品。包含一个接口和若干个实现类,以及一个工厂来生产这些实现类。我们以生产Fruit来加以说明

类图如下:

接口Fruit

package org.czty.simpleFactory;/** * Created by Chris chen on 2017/8/5. */public interface Fruit {    public void display();}
实现类Apple

package org.czty.simpleFactory;/** * Created by Chris chen on 2017/8/5. */public class Apple implements Fruit{    @Override    public void display() {        System.out.println("生产了一个苹果");    }}
实现类Orange

package org.czty.simpleFactory;/** * Created by Chris chen on 2017/8/5. */public class Orange implements Fruit {    @Override    public void display() {        System.out.println("生产了一个橘子");    }}
工厂类Factory

package org.czty.simpleFactory;/** * Created by Chris chen on 2017/8/5. */public class Factory {    public Fruit create(int type) {        Fruit fruit = null;        switch (type) {            case 0:                fruit = new Apple();                break;            case 1:                fruit = new Orange();                break;        }        return fruit;    }}
测试类

package org.czty.simpleFactory;/** * Created by Chris chen on 2017/8/5. */public class Test {    public static void main(String[] args) {        Factory factory = new Factory();        factory.create(0).display();        factory.create(1).display();    }}
测试结果:

生产了一个苹果生产了一个橘子Process finished with exit code 0


总结:

简单工厂模式其实非常简单,生产实例的过程在工厂执行,并且选择的过程也是在工厂中执行的。这样如果新增了新的实现,比如香蕉,那么就要改工厂类,这就违背了可拓展的原则。而用另一种工厂方法模式很好的解决了这个问题。使得改动只发生在客户端,不会对原来的类进行修改。

多个工厂模式


类图如下:



较之上面的类图,多了一个factory,这样一旦有新的的实现加入,只需要再加入新的工厂,这样就不用改变原有的代码了。

代码只是在原有的基础上新增了两个工厂类

AppleFactory

package org.czty.simpleFactory2;/** * Created by Chris chen on 2017/8/5. */public class AppleFactory {    public Fruit createApple() {        Fruit fruit = new Apple();        return fruit;    }}
OrangeFactory

package org.czty.simpleFactory2;/** * Created by Chris chen on 2017/8/5. */public class OrangeFactory {    public Fruit createOrange() {        Fruit fruit = new Orange();        return fruit;    }}
测试类

package org.czty.simpleFactory2;/** * Created by Chris chen on 2017/8/5. */public class Test {    public static void main(String[] args) {        Fruit fruit = new AppleFactory().createApple();        fruit.display();        fruit = new OrangeFactory().createOrange();        fruit.display();    }}
结果

生产了一个苹果生产了一个橘子Process finished with exit code 0


结果和简单工厂模式一样,但是多个工厂模式具有更好的可拓展性,且把判断逻辑移到了客户端。但同样带来问题,每个实现对应一个工厂类太麻烦了,解决办法就是反射机制。

Claa.forName("package.class").newInstance();
我们修改一下工厂类

ReflectFactory

package org.czty.simpleFactory2;/** * Created by Chris chen on 2017/8/5. */public class ReflectFactory {    public static Fruit getInstance(String className) {        Fruit fruit = null;        try {            fruit = (Fruit) Class.forName(className).newInstance();        }catch (Exception e) {            e.printStackTrace();        }        return fruit;    }}
测试类

package org.czty.simpleFactory2;/** * Created by Chris chen on 2017/8/5. */public class Test {    public static void main(String[] args) {        /*Fruit fruit = new AppleFactory().createApple();        fruit.display();        fruit = new OrangeFactory().createOrange();        fruit.display();*/原来的代码        Fruit fruit = ReflectFactory.getInstance("org.czty.simpleFactory2.Apple");        if (fruit != null) {            fruit.display();        }    }}
发现只需要一个工厂就能搞定,避免了为每一个实现类单独写一个工厂了。


抽象工厂模式

工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式。与之前不同,这里不再是一个接口,而是两个接口,即划分事务的方式存在了两个维度。创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。
用猫和狗来做例子,猫有白猫和黑猫,狗有白狗和黑狗。

维度1:按动物划分,猫和狗

维度2:按颜色划分,黑和白

对于接口是按照动物类型划分的。而工厂则是按照颜色类型划分的。即一个工厂可以生产一个颜色的两种动物类型。类图如下


代码实现

Dog接口

package org.czty.abstractFactory;/** * Created by Chris chen on 2017/8/5. */public interface Dog {    public void create();}
Cat接口

package org.czty.abstractFactory;/** * Created by Chris chen on 2017/8/5. */public interface Cat {    public void create();}
BlackDog实现类

package org.czty.abstractFactory;/** * Created by Chris chen on 2017/8/5. */public class BlackDog implements Dog {    @Override    public void create() {        System.out.println("生产了一只黑狗");    }}
WhiteDog实现类

package org.czty.abstractFactory;/** * Created by Chris chen on 2017/8/5. */public class WhiteDog implements Dog {    @Override    public void create() {        System.out.println("生产了一只白狗");    }}
BlackCat实现类

package org.czty.abstractFactory;/** * Created by Chris chen on 2017/8/5. */public class BlackCat implements Cat {    @Override    public void create() {        System.out.println("生产了一只黑猫");    }}
WhiteCat实现类

package org.czty.abstractFactory;/** * Created by Chris chen on 2017/8/5. */public class WhiteCat implements Cat {    @Override    public void create() {        System.out.println("生产了一只白猫");    }}
BlackFactory工厂类

package org.czty.abstractFactory;/** * Created by Chris chen on 2017/8/5. */public class BlackFactory {    public Dog createBlackDog() {        return new BlackDog();    }    public Cat createBlackCat() {        return new BlackCat();    }}
WhiteFactory工厂类

package org.czty.abstractFactory;/** * Created by Chris chen on 2017/8/5. */public class WhiteFactory {    public Dog createWhiteDog() {        return new WhiteDog();    }    public Cat createWhiteCat() {        return new WhiteCat();    }}
测试类

package org.czty.abstractFactory;/** * Created by Chris chen on 2017/8/5. */public class Test {    public static void main(String[] args) {        BlackFactory blackFactory = new BlackFactory();        blackFactory.createBlackCat().create();        blackFactory.createBlackDog().create();        WhiteFactory whiteFactory = new WhiteFactory();        whiteFactory.createWhiteCat().create();        whiteFactory.createWhiteDog().create();    }}
结果

生产了一只黑猫生产了一只黑狗生产了一只白猫生产了一只白狗Process finished with exit code 0

原创粉丝点击