设计模式-简单工厂模式

目录

案例:

想法:

问题1

修改代码

问题2

修改代码

问题3

知识点:

思考:(复制和复用)

代码

计算类

显示类

问题4

问题5

代码

问题6

代码

简单工厂模式

定义

模式结构:

​编辑 案例

代码

分析:

案例:

代码

简单工厂优缺点


案例:

使用任意一种面向对象语言实现一个计算机控制台程序,要求输入两个数和运算符号,得到结果

想法:

public class one {
    public static void main(String[] args) {
        System.out.println("输入一个数");
        Scanner sc=new Scanner(System.in);
        String a = sc.next();
        System.out.println("输入一个数");
        Scanner sc1=new Scanner(System.in);
        String b = sc.next();
        System.out.println("输入一个运算符号:+-*/");
        Scanner sc2=new Scanner(System.in);
        String c = sc.next();
        if (c=="+"){
            System.out.println(a+b);
        }

问题1

这个暴露出很多问题 果然是看了的知识点总会在实践的时候漏洞百出

1.比较字符串的时候 应该使用的是equals而不是==

2.需要将接受到的字符串转换为整数或者浮点数,才能进行数值估算。

可以使用integer.parseInt double.parsedouble来实现类型装换

修改代码
import java.util.Scanner;

public class one {
    public static void main(String[] args) {
        System.out.println("输入一个数");
        Scanner sc=new Scanner(System.in);
        Double a = Double.parseDouble(sc.next());
        System.out.println("输入一个数");
        Scanner sc1=new Scanner(System.in);
        Double b = Double.parseDouble(sc.next());
        System.out.println("输入一个运算符号:+-*/");
        Scanner sc2=new Scanner(System.in);
        String c = sc.next();
        if (c.equals("+")){
            System.out.println(a+b);
        } else if (c.equals("/")) {
            if(b==0){
                System.out.println("错误");
            }else if(b!=0){
                System.out.println(a/b);
            }
        }
        //一样



    }
}

问题2

if那里的代码太多无用功了 接收输入那边也是太多无用的 (在接收第二个数和运算的时候,不需要再创建新的scanner对象,可以继续使用已经创建的sc对象)

修改代码
import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;

import java.util.Scanner;

public class one {
    public static void main(String[] args) {
        System.out.println("输入一个数");
        Scanner sc=new Scanner(System.in);
        Double a = Double.parseDouble(sc.next());
        System.out.println("输入一个数");
        Double b = Double.parseDouble(sc.next());
        System.out.println("输入一个运算符号:+-*/");
        String c = sc.next();
//        if (c.equals("+")){
//            System.out.println(a+b);
//        } else if (c.equals("/")) {
//            if(b==0){
//                System.out.println("错误");
//            }else if(b!=0){
//                System.out.println(a/b);
//            }
//        }
        switch (c){
            case "+":
                System.out.println(a+b);
                break;
            case"/":
                if (b==0){
                    System.out.println("arr");
                }else if (b!=0){
                    System.out.println(a/b);
                    break;
                }
        }
        //一样



    }
}

问题3

题目的要求使用面向对象编程去实现这个代码 我们碰到问题总是以直觉的思维去做的话总是会使得程序不容易去维护 扩展 更不容易去复用 代码不会高质量


知识点:

面向对象更活字印刷一个道理 活字印刷可以改字--可维护;可以重复使用--可复用;可以加字--可扩展;可以横排或者竖排--灵活性好

所以说当我们学习了面向对象的分析设计编程思想的话。我们应该开始考虑通过封装,继承,多态来吧程序的耦合性来降低。使用设计模式可以让程序更加的灵活


思考:(复制和复用)

何为复制??

ctrl c ctrl v

何为复用?

可以去重复使用

考虑到这个计算器这么可以更好的去复用 我们可以将他的计算和显示先分开

代码

计算类

public class Calculator {

    public double cal(double a, double b, String c) {
        double result = 0;

        switch (c) {
            case "+":
                result = a + b;
                break;
            case "/":
                if (b == 0) {
                    System.out.println("除数不能为0");
                } else {
                    result = a / b;
                }
                break;
            default:
                System.out.println("无效的运算符号");
        }

        return result;
    }
}

显示类

import java.util.Scanner;

public class two1 {
    public static void main(String[] args) {
        System.out.println("请输入数字 a:");
        Scanner sc = new Scanner(System.in);
        Double a = Double.parseDouble(sc.next());

        System.out.println("请输入数字 b:");
        Double b = Double.parseDouble(sc.next());

        System.out.println("请输入运算符号:");
        String c = sc.next();

        Calculator tw = new Calculator();
        double result = tw.cal(a, b, c);
        System.out.println("计算结果为: " + result);
    }
}

问题4

在自己写的代码中方法调用一下想不到

问题5

这个小案例 只运用了面向对象的封装 面向对象还有继承和多态 

就比如现在让我们去添加一个开根(sqrt)运算 我们怎么去改???

第一个想法 肯定是在运算类中修改switch中的case

但是在公司实际开发中 你为了多加一个sqrt需要让+-*/去一起陪你编译 这样如果一不小心修改了其他的 或者工资修改工资系统中 有人把其他的case也修改了 不就出大问题啦 所以说现在的代码没有很好的扩展性

代码

运算类:

public class Operation {
    public double calculate(double a, double b) {
        return 0; // 基础运算类中的计算方法,具体实现将由子类覆盖
    }
}

加减乘除分别设类

public class Addition extends Operation {
    @Override
    public double calculate(double a, double b) {
        return a + b;
    }
}
public class Division extends Operation {
    @Override
    public double calculate(double a, double b) {
        if (b == 0) {
            System.out.println("除数不能为0");
            return 0; // 或者抛出异常
        } else {
            return a / b;
        }
    }
}

问题6

这样的话想要去修改任何一个算法的话就不需要去改动其他的算法了 但是这样怎么才可以让电脑知道你是希望使用哪一个算法呢??

代码

******


简单工厂模式

定义

定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。

  • 简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式
  • 专门定义一个类来负责创建其他类的实例,可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。

模式结构:

 案例

某销售管理系统支持多种支付方式,如现金支付(CashPay)、信用卡支付(CreditcardPay)、代金券支付(VoucherPay)等。一般代码设计如下:

代码

具体类

public class juti extends ab{
    public void pay(){
        
    }
}

抽象类

public abstract class ab{
    public abstract void pay();
}

工厂类

public class paymethodFactory {
    public static ab getpaymethod(String type){
        if (type.equalsIgnoreCase("cash")){
            return new juti();
        }
    }
}

分析:

案例:

某电视机厂专为各知名电视机品牌代工生产各类电视机,当需要海尔牌电视机时只需要在调用该工厂的工厂方法时传入参数“Haier”,需要海信电视机时只需要传入参数“Hisense”,工厂可以根据传入的不同参数返回不同品牌的电视机。现使用简单工厂模式来模拟该电视机工厂的生产过程

代码

工厂类

其他类

简单工厂优缺点

  • 简单工厂模式优点:
  • 实现了对象创建和使用的分离
  • 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可
  • 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性
  • 简单工厂模式缺点:
  • 工厂类集中了所有产品的创建逻辑,职责过重一旦不能正常工作,整个系统都要受到影响
  • 增加系统中类的个数,增加了系统的复杂度和理解难度系统扩展困难,一旦添加新产品不得不修改工厂逻辑
  • 由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构,工厂类不能得到很好地扩展
  • 简单工厂模式适用环境:
  • 工厂类负责创建的对象比较少,由于创建对象比较少,不会造成工厂方法中的逻辑太过复杂。
  • 客户端只知道传入工厂类的参数,对于如何创建对象不关心:客户端既不需要关心创建细节,甚至于连类名都不需要记住,只需要知道类型所对应的参数即可。
上一篇:深入浅出计算机网络 day.8 第三章 数据链路层 3.4 ②


下一篇:安卓Android 架构模式及UI布局设计-二、 Android SDK 中最常用的布局类