zoukankan      html  css  js  c++  java
  • 工厂模式

    工厂模式

    什么是工厂模式

    • 工厂是生产产品的,在程序中,任何可以产生对象的方法或者类都可以称为工厂,比如单例模式。
    • 那么有了new之后,为什么还要有工厂呢,它是为了可以更加灵活地控制生产过程。

    举例

    以生产手机为例,如果现在要生产多款手机,简单地做法就是针对每种手机创建一个类,生产每种手机的时都需要重新new

    package FactoryPattern;
    
    class iphone{
        public void call(){
            System.out.println("拨电话");
        }
    }
    
    class HuaWei{
        public void call(){
            System.out.println("拨电话");
        }
    }
    
    class Mi{
        public void call(){
            System.out.println("拨电话");
        }
    }
    
    public class Main {
        iphone phone = new iphone();
        public static void main(String[] args) {
    
        }
    }
    

    每次创建对象都需要修改代码,那么有没有办法解决呢?可以设置一个手机接口,通过多态的方法创建,这样把手机类别写到配置文件就行了。

    package FactoryPattern;
    
    
    interface Phone{
        void call();
    }
    
    class iphone implements Phone{
        public void call(){
            System.out.println("拨电话");
        }
    }
    
    class HuaWei implements Phone{
        public void call(){
            System.out.println("拨电话");
        }
    }
    
    class Mi implements Phone{
        public void call(){
            System.out.println("拨电话");
        }
    }
    
    public class Main {
    
        public static void main(String[] args) {
            Phone phone = new iphone();
            phone.call();
        }
    }
    

    那么如果生产手机时每种手机经过一些不同的预处理呢,这时候生产对象的代码又会来回变,怎么解决这个问题。

    简单工厂

    可以通过简单工厂来解决上述这个问题,将所有类型手机的创建封装到一个工厂类中。

    package FactoryPattern;
    //简单工厂
    public class PhoneFactory {
        public iphone createIphone(){
            //before process
            return new iphone();
        }
    
        public HuaWei createHuaWei(){
            return new HuaWei();
        }
    
        public Mi createMi(){
            return new Mi();
        }
    }
    

    那么这种方法有什么缺点呢,可以看出,如果要新添加一种类型的手机,就要重写这个类,并且创函数中的处理都是写死的。那么如何解决这个问题呢,可以采用工厂方法来解决。

    工厂方法

    可以把每个手机类定义为一个工厂,新添加一种类型的手机就创建一个新的工厂即可

    package FactoryPattern;
    
    class iphoneFactory {
        public Phone createIphone(){
            System.out.println("生产个Iphone");
            return new iphone();
        }
    }
    class HuaWeiFactory {
        public Phone createHuaWei(){
            System.out.println("生产个HuaWei");
            return new HuaWei();
        }
    }
    class MiFactory {
        public Phone createMi(){
            System.out.println("生产个Mi");
            return new Mi();
        }
    }
    
    

    抽象工厂

    工厂方法在产品的维度上很好扩展,那么对于产品族呢,如果现在是创建手机,电脑,平板三件套呢,该如何做呢。一种简单的做法如下

    class iphone{
        public void call(){
            System.out.println("拨电话");
        }
    }
    
    class Macbook{
        public void work(){
            System.out.println("办公");
        }
    }
    
    class Ipad{
        public void play(){
            System.out.println("玩平板");
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            iphone iphone = new iphone();
            iphone.call();
    
            Macbook macbook = new Macbook();
            macbook.work();
    
            Ipad ipad = new Ipad();
            ipad.play();
        }
    }
    

    这种做法,每次创建一个一种新的产品族,比如要创建华为三件套就要重写代码。那么如何解决这个问题呢,抽象工厂就可以用来解决这个问题。主要的步骤如下:

    • 将手机,电脑和平板封装为抽象类,所有类型的手机,电脑和平板继承该抽象类
    • 创建一个抽象工厂类,类中声明创建手机,电脑和平板的抽象函数,所有的产品族继承该抽象工厂类
    • 现在创建新的产品族时,只需实现一个新的工厂类。
    package AbstractPattern;
    
    abstract class Phone{
        abstract void call();
    }
    
    abstract class Computer{
        abstract void work();
    }
    
    abstract class Pad{
        abstract void play();
    }
    
    
    
    abstract class AbstractFactory {
        abstract Phone createPhone();
        abstract Computer createComputer();
        abstract Pad createPad();
    }
    
    
    class iphone extends Phone{
        public void call(){
            System.out.println("拨电话");
        }
    }
    
    class Macbook extends Computer{
        public void work(){
            System.out.println("办公");
        }
    }
    
    class Ipad extends Pad{
        public void play(){
            System.out.println("玩平板");
        }
    }
    
    
    class AppleFactory extends AbstractFactory{
        @Override
        Phone createPhone() {
            return new iphone();
        }
    
        @Override
        Computer createComputer() {
            return new Macbook();
        }
    
        @Override
        Pad createPad() {
            return new Ipad();
        }
    }
    public class Main {
    
        public static void main(String[] args) {
    
            AbstractFactory appleFactory = new AppleFactory();
            Phone phone = appleFactory.createPhone();
            phone.call();
            Computer computer = appleFactory.createComputer();
            computer.work();
            Pad pad = appleFactory.createPad();
            pad.play();
        }
    }
    
  • 相关阅读:
    日期 根据所选日期 获取 之后N天的日期
    错误退出登录
    挂载路由导航守卫 router
    缓存 ssessionStorage&localStorage
    vue项目 第三方图标库阿里图库
    码云新建仓库 以及本地上传
    sql的四种连接-左外连接、右外连接、内连接、全连接
    C#中常用修饰符
    接口的隐式和显式实现
    C#break、continue、return、goto
  • 原文地址:https://www.cnblogs.com/happysml/p/13868018.html
Copyright © 2011-2022 走看看