设计模式-工厂模式

工厂模式:在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

目标:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

分类:

1、简单工厂

2、工厂方法

3、抽象工厂


一、简单工厂

个人理解:多个类(类似于猫、狗),继承一个抽象类或者实现一个接口(动物),他们有相同的方法(比如叫),最后只需要一个工厂(动物),需要什么就制造什么(让哪个动物叫,就传入哪个动物)。

UML图解(画图工具出了点问题,就从别的地方找了个图,从哪借鉴的会在文章结尾标出):

(大家可以把猫狗鸡鸭想象成加减乘除,运算类就是动物类)

代码:

public class Main {
    public static void main(String[] args) {
        AnimalFactory.say(new Cat());
        AnimalFactory.say(new Dog());
    }
}
interface Animal{
    void say();
}

class Cat implements Animal{
    @Override
    public void say() {
        System.out.println("miaomiaomiao");
    }

}

class Dog implements Animal{
    @Override
    public void say(){
        System.out.println("wangwangwang");
    }
}

class AnimalFactory{
    public static void say(Animal a){
        a.say();
    }
}

优点:静态方法,根据条件判断需要哪个就用哪个

缺点:不同的产品有不同的参数,本工厂就不支持,扩展性差(违反开闭原则)


二、工厂方法

个人理解:所有的类都有对应的工厂,而这些工厂还有一个工厂(运算工厂,也属于运算类),当需要新的产品时,增加工厂类和对应的产品类即可

UML图解:


 

代码:

//动物
public interface Animal {
    void say();
}
//猫
public class Cat implements Animal{
    @Override
    public void say() {
        System.out.println("miao!");
    }
}
//猫工厂
public class CatFactory {
    public Animal create() {
        System.out.println("a cat created!");
        return new Cat();
    }
}
//狗
public class Dog implements Animal{
    @Override
    public void say() {
        System.out.println("wang!");
    }
}
//狗工厂
public class DogFactory {
    public Animal create() {
        System.out.println("a dag created!");
        return new Dog();
    }
}
//需要什么就调用工厂生产什么并实现方法
public class Main {
    public static void main(String[] args) {
        Animal a = new CatFactory().create();
        a.say();
    }
}

优点:横向扩展比较方便,例如上图,需要添加新的运算具体的类的时候,添加类及其对应的工厂即可。

缺点:如果从一个对象的整体来拓展就很难实现(例如运算只是这个对象的一个属性,要是需要其他的属性一起修改),类似于产品一族整体修改


三、抽象工厂(在书籍讲解的时候工厂方法和抽象工厂是分开的,我给放到一起)

个人理解:

从上到下,先确定是这个工厂能产生什么(都有什么属性,例如代码就是交通工具和食物),然后创建具体的类,然后再创建不同的工厂去生产不同属性(交通工具和食物),最后需要什么工厂,就去调用什么工厂,将抽象变为好理解的。

UML图解(借鉴的图,看着有些复杂,只能细品了):

 

代码:

食物分类(可以创建多个食物)

//食物
public abstract class Food {
   abstract void printName();
}
//面包(具体的食物)
public class Bread extends Food{
    public void printName() {
        System.out.println("我是面包");
    }
}
//米饭(具体的食物)
public class Rice extends Food{
    public void go() {
        System.out.println("我是大米饭");
    }
}

交通方式分类(可以创建多个交通方式)

public abstract class Vehicle { //interface
    abstract void go();
}

public class Car extends Vehicle{

    public void go() {
        System.out.println("Car go wuwuwuwuw....");
    }
}


public class Broom extends Vehicle{
    public void go() {
        System.out.println("Car go wuwuwuwuw....");
    }
}

创建抽象工厂,分别生产这些东西

public abstract class AbastractFactory {
    abstract Food createFood();
    abstract Vehicle createVehicle();
}

创建具体的实现工厂(要生产什么的地方)

//现实世界人吃什么,用什么交通工具
public class ModernFactory extends AbastractFactory {
    @Override
    Food createFood() {
        return new Bread();
    }

    @Override
    Vehicle createVehicle() {
        return new Car();
    }

}

//魔法世界人吃什么,用什么交通工具
public class MagicFactory extends AbastractFactory {
    @Override
    Food createFood() {
        return new Rice();
    }

    @Override
    Vehicle createVehicle() {
        return new Broom();
    }

}

//最后怎样调用(调用实现之后的工厂,并且创建出需要的食物和交通工具)

public class Main {
    public static void main(String[] args) {
        //创建现实世界工厂
        AbastractFactory f = new ModernFactory();
        Vehicle c = f.createVehicle();
        c.go();
        Food b = f.createFood();
        b.printName();
        //创建魔法世界工厂
        /*AbastractFactory af = new MagicFactory();
        Vehicle vc = af.createVehicle();
        vc.go();*/
    }
}

优点:如果想拓展产品一族很方便,创建新的工厂即可,不用修改原来的代码(开闭原则)

缺点:如果想拓展具体产品一族中的一个属性不合适


最后总结:

工厂模式还是要自己去手敲一边代码才能理解,而且这个模式的产生的目的就是解耦,具体的实现方式大家可以学习下

Spring IOC(控制反转),Spring 将这个用的淋漓尽致。

最后感谢:芹泽 https://blog.csdn.net/u012218309/article/details/81333631 提供的UML图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值