GOF23-工厂模式

引申复习面向对象的设计的六大原则,一些设计模式中就体现了这类原则

  1. 单一职责:一个合理的类功能应该只有一个,消除耦合减少需求变化对代码的修改

  2. 开闭原则:一个类应该对扩展开启,对修改关闭。降低程序模块之间的耦合度,增加扩展性

  3. 里氏替换原则:子类应该能替换基类。 能够很好的实现功能的调整和升级,并且不影响客户端调用

  4. 依赖倒换原则:设计依赖于抽象而不是依赖于具体化。

  5. 接口隔离原则:划分接口应该单一细致,让系统容易实现重构,对接口修改时影响较少。

  6. 迪米特法则:一个类尽可能少的去了解其他对象 

这些原则其实最后的目的是为了程序中模块分工明确,便于升级和调整。

工厂模式:实例化对象,用工厂方法代替new操作,将实现类和对象的创建统一管理和控制,从而将调用者和实现类解耦。

工厂模式也分为三种,简单工厂模式(静态工厂模式)、工厂方法模式,抽象工厂模式

一、简单抽象模式(静态抽象模式)

1、UML类图

动物产品可以有Cat、Pig、Dog 客户端来生成产品时需要与每一个具体的产品产生联系,比如 Animal cat = new Cat();这样 对象的生成和控制全在客户端client。 不便于管理,那么我们可以将对象的生成交给第三方来管理。 客户端需要产品 只要通知一个组件 我需要什么对象,组件返回相应对象满足客户端;那么对象的生成相对于客户端透明, 便于统一管理。这就是简单抽象模式。

2、产品类: Cat 、Pig、Dog实现Animal接口

package factory.simple;

public interface Animal {
    public void say();
}
package factory.simple;

public class Cat implements Animal {
    public void say() {
        System.out.println("喵喵喵");
    }
}
package factory.simple;

public class Dog implements Animal {
    public void say() {
        System.out.println("汪汪汪");
    }
}
package factory.simple;

public class Pig implements Animal {
    public void say() {
        System.out.println("哼哼哼");
    }
}

3、工厂类:SimpleFactory

package factory.simple;
public class SimpleFactory01 {
    //第一种简单工厂模式
    public static Animal creatAnimal(String type){
        if("cat".equals(type)){
            return new Cat();
        }else if("pig".equals(type)){
            return new Pig();
        }else{
            return null;
        }
    }

    //第二种简单工厂模式
    public static Animal creatCat(){
        return new Cat();
    }
    public static Animal creatPig(){
        return new Pig();
    }
}

4、客户端

package factory.simple;

public class Client1 {
    public static void main(String[] args) {
        Animal cat = SimpleFactory01.creatAnimal("cat");
        cat.say();
        Animal pig = SimpleFactory01.creatAnimal("pig");
        pig.say();
        
        Animal cat2 = SimpleFactory01.creatCat();
        cat2.say();
        Animal pig2 = SimpleFactory01.creatPig();
        pig2.say();
        
    }
}

5、总结:客户端在需要动物产品时 只需要向SimpleFactory通知需要什么对象就能得到满足。实现了对象的生成与统一管理交给了工厂SimpleFactory。实现了分工。

优点:简单工厂模式实现简单。

缺点:对于新产品的添加需要对已存在的工厂代码修改,违反了开闭原则。

二、工厂方法模式

通过上面的建档工厂模式,当我们需要增加一个新的产品(alpaca羊驼)时,我们需要在原工厂内增加逻辑生成新产品,这违背了开闭原则,对扩展开放,对修改关闭。这显然不合理,那么我们可以通过工厂方法模式来解决这个问题。 我们可以将工厂类进行拆分。将产品和工厂类一一对应,那么我们需要增加新的产品时,只需要增加相应的产品类和工厂类就可以解决了。

1、UML类图

2、产品类(与简单工程类一致)

3、工厂类

package factory.method;

import factory.method.Animal;

/**
 * 工厂方法模式
 */
public interface MethodFactory {
    Animal create();
}
package factory.method;

public class CatFactory implements MethodFactory {
    public Animal create() {
        return new Cat();
    }
}
package factory.method;

public class PigFactory implements MethodFactory {
    public Animal create() {
        return new Pig();
    }
}

4、客户端

package factory.method;

public class Client {
    public static void main(String[] args) {
        Animal cat = new CatFactory().create();
        cat.say();
        Animal pig = new PigFactory().create();
        pig.say();
    }
}

5.总结:当需要新增加其他产品时,只需要增加产品类、和产品对应的工厂类。不需要对已存在的工厂类做修改,符合的开闭原则。

优点:符合开闭原则,对扩展支持良好

缺点:增加了类,增加了类的管理

三、抽象工厂模式

工厂方法模式很好的解决了简单工厂模式遗留下的扩展问题。但并不是工厂方法就是完美的存在这种情况:当我们需要同种产品存在差异时,比如我需要一个很肥的猫,需要一个瘦的猫。 如果使用抽象工厂方法模式,那么需要再增加肥的 和瘦的对应的商品类 并且增加对应的工厂类。

1、UML类图

2.产品类

package factory.abstractfactory;

public interface Animal {
    public void say();
}
package factory.abstractfactory;

public interface BigAnimal extends Animal {
}
package factory.abstractfactory;

public interface SmallAnimal extends Animal {
}
package factory.abstractfactory;

public class BigCat implements BigAnimal {
    public void say() {
        System.out.println("肥猫喵喵喵");
    }
}
package factory.abstractfactory;

public class SmallCat implements BigAnimal {
    public void say() {
        System.out.println("瘦猫嗷嗷嗷");
    }
}

3、工厂类

package factory.abstractfactory;

public interface AbstractFactory {
    public Animal createBig();
    public Animal createSmall();
}
package factory.abstractfactory;

public class CatFactory implements AbstractFactory{

    public Animal createBig() {
        return new BigCat();
    }

    public Animal createSmall() {
        return new SmallCat();
    }
}

4、客户端

package factory.abstractfactory;

public class Client {
    public static void main(String[] args) {
        Animal bigCat = new CatFactory().createBig();
        Animal smallCat = new CatFactory().createSmall();
        bigCat.say();
        smallCat.say();
    }
}

5.总结:抽象工厂类在 工厂方法的基础上对产品和产品的工厂进行再次的抽象分类。 抽象分为建为约束,那么就只能建立类似的产品进行扩展,增加了约束条件。

总结:三种工厂类  没有必须使用哪一种。 根据具体情况选择使用

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章