工厂模式

本文深入探讨工厂模式的三种类型:简单工厂、工厂方法和抽象工厂,通过具体实例(牛奶和电脑配件生产)详细解释每种模式的实现方式、优缺点及应用场景,帮助读者理解并掌握工厂模式在软件设计中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

属于创建型设计模式:分为简单工厂模式,方法工厂模式和抽象工厂模式


简单工厂模式:可以类比小作坊(只有一个车间,可以生产多种产品),用一个类来负责产生所有继承公共父接
               口的产品类的实例,让用户可以只关心结果,不再关心生产的过程,直接告诉工厂类(类似到小作坊购买就行)
               需求,隐藏了产品类的具体实现过程。(具体实现是:定义抽象产品可生产多个产品,然后用有个加工类负责实现这些产品)

UML:


            
               
               
               
工厂方法模式:类似规模化,标准化的大工厂,有生产各个具体产品的车间,这个时候工厂是抽象的,当生产某种具体的产品
                时,需要指定特定的车间才能生产出来,也是对用户隐藏了产品的具体实现,只需要关心结果就行。(具体的实
                现:定义一个抽象产品可生产多个产品,定义一个抽象工厂可生产多个具体的车间负责加工特定的产品)

UML:


                
                

抽象工厂模式:可以类比流水线,当产品里有多于一个的产品族(位于不同等级结构的相关联产品,比如同为鼠标,不同厂家生产的鼠标质量是不同的),
                抽象模式可以解决接口选择的问题,向客户端提供一个接口,使客户端在不必指定具体产品的情况下,创建多个产品族中的产品对象。
                (具体实现见代码)

UML:


                


                
简单工厂模式和工厂方法模式的优缺点和比较:
(1)两者结构不同,简单工厂模式只有一个多种产品的实现类,不易扩展,而且应为需要传入一个产品类参数才能获得相应的产品,容易出错,而工厂方法模式核心是一个抽象工厂类,可以根据抽象工厂类做工厂的扩展
(2)前者不符合开闭原则,因为当生产一个新产品时,必须修改实现类,后者只需要添加一个新的产品类和实现该产品具体工厂类就行,不需要修改客户端
(3)简单工厂模式客户端需要知道具体产的品类,而后者只需要知道相应的车间(工厂)就行
(4)工厂方法模式利用面向对象的多态性和里式代换原则,抽象工厂只提供生产某类产品的接口,有子类确定自己要生产的对象,使得系统易于扩展
(5)对于后者的缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,
   同时也增加了系统具体类的依赖。这并不是什么好事。            
                
                
抽象工厂的优缺点:
优点:当针对同组产品的创建新的生产线,容易增加。
                
缺点:新的产品族的扩展非常困难,需要修改抽象工厂,还需修改继承了抽象工厂的相应子工厂。灵活性差    

简单工厂模式代码:(用牛奶举例子):

需要一个接口:牛奶(产生各种品牌的牛奶)
public interface Milk {
    Milk  getMilk();

}


伊利品牌牛奶 Implements Milk

public class YiLi implements Milk{

    @Override
    public Milk getMilk() {
        return new YiLi();
    }
}

蒙牛品牌的牛奶 implements Milk
public class Mengniu implements Milk {
    @Override
    public Milk getMilk() {
        return new Mengniu();
    }
}

简单工厂模式是用一个类实现所有的产品类:因此需要知道客户端传来的参数,也就是需要的产品是什么
public class Sinfactory {
    public String getMilk(Milk milk) {
       if(milk instanceof YiLi) {
           return "已经获得伊利牛奶";
       }else if(milk instanceof Mengniu) {
           return "已经获得蒙牛";
       }else {
           return "无此产品";
       }


    }
}


工厂方法模式代码:(同样用牛奶举例子)
需要一个接口:牛奶(产生各种品牌的牛奶)
public interface Milk {
    Milk  getMilk();

}


伊利品牌牛奶 Implements Milk

public class YiLi implements Milk{

    @Override
    public Milk getMilk() {
        return new YiLi();
    }
}

蒙牛品牌的牛奶 implements Milk
public class Mengniu implements Milk {
    @Override
    public Milk getMilk() {
        return new Mengniu();
    }
}

然后不同于简单工厂模式:工厂方法是具体的工厂生产具体的产品
先定义一个抽象工厂接口
public interface AbstractFactory {
    public String getMilk();
}

然后实现具体的工厂
蒙牛:
public class MengniuFactory implements AbstractFactory{
    @Override
    public String getMilk() {
        return "Mengniu";
    }

}

伊利
public class YiLiFactory implements AbstractFactory {
    @Override
    public String getMilk() {
        return "YiLi";
    }
}


抽象工厂方法代码实现(设计产品族,用电脑商品举例子)
一个电脑由:鼠标,键盘....组成
现在有华硕和戴尔都生产这两个产品,华硕生产的是华硕鼠标和华硕键盘,戴尔生产的是戴尔鼠标和戴尔键盘(因为质量不同,自然产生等级结构)


定义鼠标接口:
public interface Mouse {
    public Mouse CreateMouse();
}

定义键盘接口
public interface KeyBoard {
    public KeyBoard createKeyBoard();
}

实现华硕鼠标的生产:
public class SnsvMouse implements Mouse {
    String name;
    public SnsvMouse(String name) {

        this.name = name;
    }
    @Override
    public Mouse CreateMouse() {
        return new SnsvMouse("SnsvMouse");
    }
}

实现华硕键盘的生产
public class SnsvKeyBoard implements KeyBoard {
    String name;
    public SnsvKeyBoard(String name) {
        this.name = name;
    }
    @Override
    public KeyBoard createKeyBoard() {
        return new SnsvKeyBoard("SnsvKeyBoard");
    }
}

实现戴尔鼠标的生产
public class DellMouse implements Mouse {
    String name;
    public DellMouse(String name) {
        this.name = name;
    }

    public DellMouse() {

    }

    @Override
    public Mouse CreateMouse() {
        return new DellMouse("DellMouse");
    }
}


实现戴尔键盘的生产
public class DellKeyBoard implements KeyBoard{
    String name;

    public DellKeyBoard(String name) {
        this.name = name;
    }
    @Override
    public KeyBoard createKeyBoard() {
        return  new DellKeyBoard("DellKeyBoard");
    }
}


定义一个抽象工厂:里面有获得产品(Mouse,KeyBoard)的方法
public abstract class AbstractPCFactory {
    public abstract Mouse getMouse();

    public abstract KeyBoard getKeyBoard();

}


华硕工厂产生具体的华硕产品
public class SnsvFactory extends AbstractPCFactory {
    @Override
    public Mouse getMouse() {
        return new SnsvMouse("").CreateMouse();
    }

    @Override
    public KeyBoard getKeyBoard() {
        return new SnsvKeyBoard("").createKeyBoard();

    }
}

戴尔工厂产生具体的戴尔产品
public class DellFactory extends AbstractPCFactory{


    @Override
    public Mouse getMouse() {
        return new DellMouse().CreateMouse();
    }

    @Override
    public KeyBoard getKeyBoard() {
        return new DellKeyBoard("Kell");
    }
}


电脑商城
public class PcMall {
    private Mouse mouse;
    private KeyBoard keyboard;

    public void make(AbstractPCFactory factory) {
        mouse = factory.getMouse();
        keyboard = factory.getKeyBoard();
    }

}

只要传入你想获得的产品,传入具体的工厂就行,就可以获得相应的多个产品族中的相应对象


借助代码的实现很容易发现:对于工厂模式,针对同组产品,只需要增加一个生产线,比如如果添加一个联想品牌电脑生产键盘和鼠标
只需要LenveoFactory类,Lenveo鼠标,Lenveo键盘就行

但是当要生产新的产品族,比如硬盘
就需要在AbstractPCFactory添加生产硬盘的方法,同时还要修改所有的继承该工厂的子工厂(如SnsvFactory和DellFactory),给他们增加生产硬盘的接口,因此显得不够灵活
    
    

            

               

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值