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

    简单工厂模式

    简单工厂模式是由工厂对象决定创建哪一种产品,虽然不属于23种设计模式,但是也是工厂模式进阶的由来。

    模拟场景:

    暑假太过无聊,就自己在家打算做一个MP3播放器,其中包括播放器的程序设计也是自己来搞定的。如下结构

    image-20210606113108291

    //歌曲播放接口
    public interface ISong {
        void  Play();
    }
    
    //流行歌曲播放
    public class PopularISong implements ISong {
        @Override
        public void Play() {
            System.out.println("接下来播放流行歌曲~");
        }
    }
    
    //古典歌曲播放
    public class ClassicalSongs  implements ISong {
        @Override
        public void Play() {
            System.out.println("接下来播放古典歌曲~");
        }
    }
    
    //MP3播放操作
    public class MP3 {
        public  enum  SongType
        {
           PopularSongType,//流行歌曲
           ClassicalSongsType//古典歌曲
           //....其他类型
        }
        public ISong Pay(SongType type)
        {
            if(type==SongType.PopularSongType)
            {
                return new PopularISong();
            }
            else if(type==SongType.ClassicalSongsType)
            {
                return new ClassicalSongs();
            }
            return  null;
        }
    }
    
    public class Text {
        public static void main(String[] args) {
            //用户执行操作
            MP3 mp3=new MP3();
            mp3.Pay(MP3.SongType.PopularSongType).Play();
        }
    }
    

    image-20210606111857680

    程序终于写完了~我在沙发上惬意的用MP3放着流行歌曲,奶奶走过来问我能不能放戏曲,我摸了摸脑袋,说:“也可以”。不过你得等我一下。

    1个小时之后,经过重新拆卸硬件,编写代码,增加了戏曲的类,又重新修改了MP3类中if else分支。

    else  if(type==SongType.TraditionalOperaType)//戏曲
    {
        //.....
    }
    

    给奶奶用了之后,很满意还告诉我爸表扬我,我爸知道了嚷嚷要听相声。我心想这不是又要再去写一遍代码.....这显然不行。

    image-20210606122402537

    简单工厂模式中包含了必要的逻辑判断,根据用户选择的条件动态实例化生成相关的类,明确区分了各自的职责和权力。但是这里也违反了开放-封闭原则,工厂类集中了所有的逻辑判断,一旦要增加一个还得修改逻辑判断的代码。

    工厂模式

    有了上述的经验,我决定重新改写程序,以防止他们又想听其它类型的歌曲,我又要重新修改代码逻辑判断。

    //工厂类
    public interface IFactory {
        ISong CreateSong();
    }
    
    //产品歌曲类
    public interface ISong {
        void  Play();
    }
    

    具体工厂类:

    //具体工厂类 用于创建流行歌曲
    public class PopularSongFactory  implements  IFactory{
        @Override
        public ISong CreateSong() {
            return  new PopularISong();
        }
    }
    
    //具体工厂类 用于创建古典歌曲
    public class ClassicalSongsFactory implements  IFactory{
        @Override
        public ISong CreateSong() {
            return new ClassicalSongs();
        }
    }
    

    具体歌曲类:

    //具体歌曲类:古典
    public class ClassicalSongs  implements ISong {
        @Override
        public void Play() {
            System.out.println("接下来播放古典歌曲~");
        }
    }
    
    //具体歌曲类:流行
    public class PopularISong implements ISong {
        @Override
        public void Play() {
            System.out.println("接下来播放流行歌曲~");
        }
    }
    

    用户操作层面:

    public static void main(String[] args) {
        //用户执行操作
        IFactory factory=new ClassicalSongsFactory();//古典工厂  只需要更改这里的类型,选择权交给用户去生成对应的实例
        ClassicalSongs songs= (ClassicalSongs) factory.CreateSong();
        songs.Play();
    }
    

    image-20210606130429960

    image-20210606131847206工厂模式把要决定实例化哪一个工厂的选择判断放到了客户端,保持了简单工厂模式的优点又克服了缺点,不需要做大的变动就可以改变,降低了程序的耦合,但是每需要增加一个类型的时候,又需要创建一个产品和工厂。这个可以利用反射来解决分支判断的问题。

  • 相关阅读:
    软件工程实践2017结对项目——第一次作业
    软件工程实践2017第二次作业
    软件工程实践2017第一次作业
    [LeetCode] 72. Edit Distance(最短编辑距离)
    [LeetCode] 342. Power of Four(位操作)
    [LeetCode] 477. Total Hamming Distance(位操作)
    [LeetCode] 421. Maximum XOR of Two Numbers in an Array(位操作)
    [LeetCode] 260. Single Number III(位操作)
    [LeetCode] 137. Single Number II (位操作)
    IntelliJ IDEA快捷键
  • 原文地址:https://www.cnblogs.com/cg-ww/p/14855131.html
Copyright © 2011-2022 走看看