设计模式学习之——简单工厂、工厂方法、抽象工厂方法

设计模式学习

1.简单工厂

  简单工厂定义一个类来专职负责创建其他类的实例,从而使程序可以在运行时决定具体创建哪个类的实例。

  角色:抽象产品、具体产品、简单工厂角色。

①DecoderFactory.java

package simplefactory;

public class DecoderFactory {
    
    public static Decoder createDecoder(String fileName){
        // 读取文件的扩展名
        String fileNameExt = fileName.substring(fileName.lastIndexOf('.'),fileName.length());
        
        if(fileNameExt.equals(".mp3")){
            return new Mp3Decoder();
        }else if(fileNameExt.equals(".wma")){
            return new WmaDecoder();
        }
        else return null;
    }
}

Decoder.java

package simplefactory;

// 抽象的解码器类,对应简单工厂模式的抽象产品角色
public abstract class Decoder {
     
     public abstract void decode(String fileName);
     
}

③Mp3Decoder.java

package simplefactory;

public class Mp3Decoder extends Decoder {

    @Override
    public void decode(String fileName) {
        // 对mp3格式进行解码并回放
        System.out.println("Decode and PlayBack the music "+ fileName + "……");
    }

}

④WmaDecoder.java

package simplefactory;

public class WmaDecoder extends Decoder {

    @Override
    public void decode(String fileName) {
        // 对wma格式进行解码并回放
        System.out.println("Decode and PlayBack the music "+ fileName + "……");
    }

}

⑤SimplePlay.java 测试

package simplefactory;

public class SimplePlay {

    public static void main(String[] args) {
        // 测试引用
        //String fileName = "Santorini.mp3";
        String fileName = "Santorini.wma";
        
        Decoder decoder = DecoderFactory.createDecoder(fileName);
        decoder.decode(fileName);
        
    }

}

2.工厂方法模式

  工厂方法是简单工厂模式的进一步抽象和推广,核心的工厂类被提升为了一个抽象类,它不再负责所有产品的创建,而是将具体的创建交给它的某个子类实现。

  角色:抽象产品类(Product)、具体产品类(ConcreteProduct)、抽象工厂类(Factory)、具体工厂类(ConcreteFactory)

①Factory.java

package factorymethod;

// 抽象工厂类,对应工厂方法模式中的抽象工程角色(Factory)
public abstract class Factory {
    
    public abstract Decoder createDecoder();
    
}

②Mp3DecoderFactory.java

package factorymethod;

// Mp3 解码器工厂,只生产Mp3 解码器对象,对应于工厂方法模式中的具体工厂角色。
public class Mp3DecoderFactory extends Factory {

    @Override
    public Decoder createDecoder() {
        // TODO Auto-generated method stub
        return new Mp3Decoder();
    }
}

③WmaDecoderFactory.java

package factorymethod;

//wma 解码器工厂,只生产wma 解码器对象,对应于工厂方法模式中的具体工厂角色。
public class WmaDecoderFactory extends Factory {

    @Override
    public Decoder createDecoder() {
        // TODO Auto-generated method stub
        return new WmaDecoder();
    }
}

④Decoder.java

package factorymethod;

// 抽象的解码器类,对应简单工厂模式的抽象产品角色
public abstract class Decoder {
     
     public abstract void decode(String fileName);
     
}

⑤Mp3Decoder.java

package factorymethod;

public class Mp3Decoder extends Decoder {

    @Override
    public void decode(String fileName) {
        // 对mp3格式进行解码并回放
        System.out.println("Decode and PlayBack the music "+ fileName + "……");
    }
}

⑥WmaDecoder.java

package factorymethod;

public class WmaDecoder extends Decoder {

    @Override
    public void decode(String fileName) {
        // 对wma格式进行解码并回放
        System.out.println("Decode and PlayBack the music "+ fileName + "……");
    }
}

⑦SimplePlayer.java 测试

package factorymethod;

// 测试抽象工程使用
public class SimplePlayer {

    public static void main(String[] args) {
        
        //String fileName = "Santorini.mp3";
        String fileName = "Santorini.wma";
        
        //创建一个特定类型的解码器工厂对象
        //选择了工厂即选择了产品
        Factory factory = new Mp3DecoderFactory();
        
        //调用该工厂对象的createDecoder()方法生成一个具体的解码器产品对象
        Decoder decoder = factory.createDecoder();
        
        //使用解码器产品对象
        decoder.decode(fileName);

    }
}

3.抽象工厂模式

  抽象工厂模式提供一个创建一系列相关或相互依赖的对象的接口,而无需指定它们的具体的类。

  角色:抽象产品类(Product)、具体产品类(ConcreteProduct)、抽象工厂类(Factory)、具体工厂类(ConcreteFactory)

①Audio.java

package abstractfactorymethod;

// 抽象音频类,对应抽象工程模式中的AbstractProduct角色
public abstract class Audio {
    
    public abstract void playBack();
}

class MandarinAudio extends Audio{

    @Override
    public void playBack() {
        // TODO Auto-generated method stub
        System.out.println("播放国语");
    }
    
}

class CantoneseAudio extends Audio{

    @Override
    public void playBack() {
        // TODO Auto-generated method stub
        System.out.println("播放粤语");
    }
    
}

②Subtitle.java

package abstractfactorymethod;

//抽象字幕类,对应抽象工厂模式中的AbstractProduct角色
public abstract class Subtitle {
    
    public abstract void show();
}

class CantoneseSubtitle extends Subtitle{

    @Override
    public void show() {
        // TODO Auto-generated method stub
        System.out.println("显示粤语!");
    }
    
}

class MandarinSubtitle extends Subtitle{

    @Override
    public void show() {
        // TODO Auto-generated method stub
        System.out.println("显示国语!");
    }
    
}

③AbstractFactory.java

package abstractfactorymethod;

// 抽象工厂类,对应抽象工厂模式中的AbstractFactory角色
public abstract class AbstractFactory {
    
    public abstract Audio creatAudio();
    public abstract Subtitle createSubtitle();
    
}

④CantoneseFactory.java

package abstractfactorymethod;

public class CantoneseFactory extends AbstractFactory {

    @Override
    public Audio creatAudio() {
        // TODO Auto-generated method stub
        return new CantoneseAudio();
    }

    @Override
    public Subtitle createSubtitle() {
        // TODO Auto-generated method stub
        return new CantoneseSubtitle();
    }
    
}

⑤MandarinFactory.java

package abstractfactorymethod;

//国语版本工厂类,对应抽象工厂模式中的ConcreteFactory角色
public class MandarinFactory extends AbstractFactory {

    @Override
    public Audio creatAudio() {

        return new MandarinAudio();
    }

    @Override
    public Subtitle createSubtitle() {

        return new MandarinSubtitle();
    }

}

⑥Simpleplayer.java 测试

package abstractfactorymethod;

// 测试抽象工程使用
public class SimplePlayer {

    public static void main(String[] args) {
        
        //创建一个能生成国语音频和字幕的工厂
//        AbstractFactory aFactory = new MandarinFactory();

        //创建一个能生成粤语音频和字幕的工厂
        AbstractFactory aFactory = new CantoneseFactory();
        
        //生产音频类产品,实际生产出什么产品由工厂类对象所限定
        Audio audio = aFactory.creatAudio();
        
        //生产字幕类产品,实际生产什么产品有工厂类对象所限定
        Subtitle subtitle = aFactory.createSubtitle();
        
        audio.playBack();
        subtitle.show();
    }

}