编程设计模式 -- (工厂设计)

一 、工厂设计模式

需求 : 举办晚会.

开始 : 晚会开始了…
节目1 : 刘德华演唱 <冰雨> 歌曲 …
节目2 : 少女时代跳 <Gee Gee Gee> 舞曲 …
节目3 : 赵本山表演 <卖拐> 节目 …
结束 : 晚会太棒了, 难忘今宵… 

实现一 : 面向打印编程

public class EveningParty {
    public static void main(String[] args) {
        System.out.println("开始 : 晚会开始了…");
        System.out.println("节目1 : 刘德华演唱 <冰雨> 歌曲 …");
        System.out.println("节目2 : 少女时代跳 <Gee Gee Gee> 舞曲 …");
        System.out.println("节目3 : 赵本山表演 <卖拐> 节目 …");
        System.out.println("结束 : 晚会太棒了, 难忘今宵…");
    }
}

这里写图片描述


实现二 : 面向对象编程

准备数据:

LiuDeHua类

public class LiuDeHua  {

    public void sing() {
        System.out.println("节目1 : 刘德华演唱 <冰雨> 歌曲 …");
    }
}

GirlsGeneration类

public class GirlsGeneration  {

    public void dance() {
        System.out.println("节目2 : 少女时代跳 <Gee Gee Gee> 舞曲 …");
    }
}

ZhaoBenShan类

public class ZhaoBenShan  {

    public void perform() {
        System.out.println("节目3 : 赵本山表演 <卖拐> 节目 …");
    }
}

实现代码

public class EveningParty {
    public static void main(String[] args) {

        System.out.println("开始 : 晚会开始了…");

        // 1. 创建一个 `刘德华` 对象
        LiuDeHua liuDeHua = new LiuDeHua();
        liuDeHua.sing();

        // 2. 创建一个 `少女时代` 对象
        GirlsGeneration girls = new GirlsGeneration();
        girls.dance();

        // 3. 创建一个 `赵本山` 对象
        ZhaoBenShan zhaoBenShan = new ZhaoBenShan();
        zhaoBenShan.perform();

        System.out.println("结束 : 晚会太棒了, 难忘今宵…");
    }
}

这里写图片描述

现在,刘德华通告满了来不了,怎么办?请张学友唱歌也可以啊。少女时代解散了不能来跳舞了,怎么办?我请少女团伙过来。本山大叔不来演小品了,我请刘谦来变魔术吧。

ZhangXueYou类

public class ZhangXueYou {

    public void sing() {
        System.out.println("节目1 : 张学友演唱 <一路上有你> 歌曲...");
    }
}

GirlsTeam类

public class GirlsTeam {

    public void dance() {
        System.out.println("节目2 : 少女团伙跳 <京东不太热> 舞曲...");
    }
}

LiuQian类

public class LiuQian  {

    public void perform() {
        System.out.println("节目3 : 刘谦表演 <大变死人> 节目...");
    }
}

代码实现

public class EveningParty {
    public static void main(String[] args) {

        System.out.println("开始 : 晚会开始了…");

        // 1. 创建一个 `张学友` 对象
        ZhangXueYou zhangXueYou = new ZhangXueYou();
        zhangXueYou.sing();

        // 2. 创建一个 `少女时代` 对象
        GirlsTeam girls = new GirlsTeam();
        girls.dance();

        // 3. 创建一个 `刘谦` 对象
        LiuQian liuQian = new LiuQian();
        liuQian.perform();

        System.out.println("结束 : 晚会太棒了, 难忘今宵…");
    }
}

实现三 : 面向接口编程

我们发现了,需求是举办舞会,表演节目是谁我不管,只要晚会举行了就好。
要唱歌的就来一个唱歌的、要跳舞的就来一个跳舞的、要表演的就来一个会表演的就行。
所以我们可以让对象实现接口来继续。

需求 : 举办晚会.

开始 : 晚会开始了…
节目1 : 刘德华演唱 <冰雨> 歌曲 …                     找一个唱歌的.
节目2 : 少女时代跳 <Gee Gee Gee> 舞曲 …              找一个跳舞的.
节目3 : 赵本山表演 <卖拐> 节目 …                     找一个表演的.
结束 : 晚会太棒了, 难忘今宵… 

Singable 接口

public interface Singable {
    void sing();
}

Dancable 接口

public interface Dancable {
    void dance();
}

Performable 接口

public interface Performable {
    void perform();
}

让LiuDeHua、ZhangXueYou实现Singable 接口;

public class LiuDeHua implements Singable {

    @Override
    public void sing() {
        System.out.println("节目1 : 刘德华演唱 <冰雨> 歌曲 …");
    }
}
public class ZhangXueYou implements Singable {

    @Override
    public void sing() {
        System.out.println("节目1 : 张学友演唱 <一路上有你> 歌曲...");
    }
}
GirlsGeneration、GirlsTeam实现 Dancable 接口

public class GirlsGeneration implements Dancable {

@Override
public void dance() {
    System.out.println("节目2 : 少女时代跳 <Gee Gee Gee> 舞曲 …");
}

}

public class GirlsTeam implements Dancable {

    @Override
    public void dance() {
        System.out.println("节目2 : 少女团伙跳 <京东不太热> 舞曲...");
    }
}

ZhaoBenShan、LiuQian实现 Performable 接口

public class ZhaoBenShan implements Performable {

    @Override
    public void perform() {
        System.out.println("节目3 : 赵本山表演 <卖拐> 节目 …");
    }
}
public class LiuQian implements Performable {

    @Override
    public void perform() {
        System.out.println("节目3 : 刘谦表演 <大变死人> 节目...");
    }
}

实现代码:

public class EveningParty {
    public static void main(String[] args) {

        System.out.println("开始 : 晚会开始了…");

        // 1. 创建一个 `张学友` 对象
        Singable s = new ZhangXueYou();
        s.sing();

        // 2. 创建一个 `少女团伙` 对象
        Dancable d = new GirlsTeam();
        d.dance();

        // 3. 创建一个 `刘谦` 对象
        Performable p = new LiuQian();
        p.perform();

        System.out.println("结束 : 晚会太棒了, 难忘今宵…");
    }
}
public class EveningParty {
    public static void main(String[] args) {

        System.out.println("开始 : 晚会开始了…");

        // 1. 创建一个 `刘德华` 对象
        Singable s = new LiuDeHua();
        s.sing();

        // 2. 创建一个 `少女时代` 对象
        Dancable d = new GirlsGeneration();
        d.dance();

        // 3. 创建一个 `赵本山` 对象
        Performable p = new ZhaoBenShan();
        p.perform();

        System.out.println("结束 : 晚会太棒了, 难忘今宵…");
    }
}

实现四 : 工厂设计模式编程
换人的流程好像变简单了。
但是,我的主业务逻辑是举办晚会, 到底来谁, 不重要. 那么为什么每次换人时, 我的主业务逻辑都需要不停修改呢 ???。
我们应该将晚会需要的 对象 交给一个独立的类提供. 这个类就被称为 晚会工厂类. PartyFactory. 作用: 为主业务逻辑提供需要的对象.
这样就实现了,我的主业务逻辑不变,需要的对象由晚会的工厂类来实现。

// 工厂设计模式 : 配置文件 + 反射

import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;

public class PartyFactory {
    // 属性
    private static final Properties prop;

    // 静态代码块
    static {
        prop = new Properties();

        try {
            prop.load(new FileReader("party.properties"));
        } catch (IOException e) {
            throw new RuntimeException("配置文件加载失败!");
        }
    }

    public static Singable getSingable() {
        // 1. 根据 key 获取 prop 对象中的 value
        String className = prop.getProperty("Singable");
        try {
            // 2. 反射创建对象
            Class<?> cls = Class.forName(className);
            Object o = cls.getDeclaredConstructor().newInstance();

            // 3. 强转, 并返回
            return (Singable) o;
        } catch (Exception e) {
            throw new RuntimeException("对象创建失败!");
        }
    }

    public static Dancable getDancable() {
        // 1. 根据 key 获取 prop 对象中的 value
        String className = prop.getProperty("Dancable");
        try {
            // 2. 反射创建对象
            Class<?> cls = Class.forName(className);
            Object o = cls.getDeclaredConstructor().newInstance();

            // 3. 强转, 并返回
            return (Dancable) o;
        } catch (Exception e) {
            throw new RuntimeException("对象创建失败!");
        }
    }

    public static Performable getPerformable() {
        // 1. 根据 key 获取 prop 对象中的 value
        String className = prop.getProperty("Performable");
        try {
            // 2. 反射创建对象
            Class<?> cls = Class.forName(className);
            Object o = cls.getDeclaredConstructor().newInstance();

            // 3. 强转, 并返回
            return (Performable) o;
        } catch (Exception e) {
            throw new RuntimeException("对象创建失败!");
        }
    }
}

配置文件 : party.properties

#Singable=cn.itcast.party.LiuDeHua
#Dancable=cn.itcast.party.GirlsGeneration
#Performable=cn.itcast.party.ZhaoBenShan

Singable=cn.itcast.party.ZhangXueYou
Dancable=cn.itcast.party.GirlsTeam
Performable=cn.itcast.party.LiuQian

实现代码:

public class EveningParty {
    public static void main(String[] args) {

        System.out.println("开始 : 晚会开始了…");

        // 1. 晚会工厂类, 给我来一个会唱歌的.
        Singable s = PartyFactory.getSingable();
        s.sing();

        // 2. 晚会工厂类, 给我来一个会跳舞的.
        Dancable d = PartyFactory.getDancable();
        d.dance();

        // 3. 晚会工厂类, 给我来一个会表演的.
        Performable p = PartyFactory.getPerformable();
        p.perform();

        System.out.println("结束 : 晚会太棒了, 难忘今宵…");
    }
}

party.properties就像是晚会表演名单一样,我只管提需求,而真正干活的是承办者也就是晚会工厂类,我不管你给我什么,我只要晚会能顺利举行就好,这就是设计过程中的 Factorty 设计模式


实现五 : 工厂设计编程优化方案

// 工厂设计模式 : 配置文件 + 反射

import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;

public class PartyFactory {
    // 属性
    private static final Properties prop;

    // 静态代码块
    static {
        prop = new Properties();

        try {
            prop.load(new FileReader("party.properties"));
        } catch (IOException e) {
            throw new RuntimeException("配置文件加载失败!");
        }
    }

    public static <T> T getInstance(Class<T> cls) {
        // 0. 获取 key
        String key = cls.getSimpleName();

        // 1. 根据 key 获取 prop 对象中的 value
        String className = prop.getProperty(key);
        try {
            // 2. 反射创建对象
            Class<?> c = Class.forName(className);
            Object o = c.getDeclaredConstructor().newInstance();

            // 3. 强转, 并返回
            return (T) o;
        } catch (Exception e) {
            throw new RuntimeException("对象创建失败!");
        }
    }
}

通过反射将代码设计的更加简洁。

配置文件 : party.properties

#Singable=cn.itcast.party.LiuDeHua
#Dancable=cn.itcast.party.GirlsGeneration
#Performable=cn.itcast.party.ZhaoBenShan

Singable=cn.itcast.party.ZhangXueYou
Dancable=cn.itcast.party.GirlsTeam
Performable=cn.itcast.party.LiuQian

实现代码:

public class EveningParty {
    public static void main(String[] args) {

        System.out.println("开始 : 晚会开始了…");

        // 1. 晚会工厂类, 给我来一个会唱歌的.
        Singable s = PartyFactory.getSingable();
        s.sing();

        // 2. 晚会工厂类, 给我来一个会跳舞的.
        Dancable d = PartyFactory.getDancable();
        d.dance();

        // 3. 晚会工厂类, 给我来一个会表演的.
        Performable p = PartyFactory.getPerformable();
        p.perform();

        System.out.println("结束 : 晚会太棒了, 难忘今宵…");
    }
}

运行程序,结果都是下面两种的一种,但是不管哪一种都实现了我举办晚会的需求。

结果1:

这里写图片描述

结果2:

这里写图片描述


工厂设计模式总结

工厂设计模式是一种强调结果而不在乎过程的设计模式。

猜你喜欢

转载自blog.csdn.net/zyrdfly/article/details/82730037
今日推荐