C#设计模式与SOLID原则实现的控制台计算器

需积分: 5 0 下载量 114 浏览量 更新于2024-12-02 收藏 2.02MB ZIP 举报
资源摘要信息:"IS421Calc-C-" 本项目是一个控制台计算器应用程序,旨在通过减少用户输入来简化数字运算。由马修·基顿(Matthew Keaton)和基思·威廉姆斯(Keith Williams)教授共同设计,其核心目标是实现一个能够接受两个数字作为输入,并进行基础运算的工具。在这个过程中,项目开发者运用了多种设计模式和面向对象编程原则,以加深对C#编程语言的理解。 知识点: 1. 设计模式应用: - 抽象工厂:用于创建一系列相关或依赖对象,而无需指定它们具体的类。这种模式可以用于计算器中的操作符生成,比如创建加法、减法等操作的实例。 - 构建者(Builder)模式:用于创建复杂对象,尤其是当对象的创建过程需要多个步骤时。在计算器应用中,可能用构建者模式来组织复杂的数学表达式的构建。 - 依赖注入(Dependency Injection):一种设计技术,用于实现控制反转(IoC),从而降低组件之间的耦合度。计算器可能通过依赖注入来管理各种操作和运算的依赖关系。 2. C# 特性: - 委托(Delegates):是C#中的一个类型,代表对具有特定参数列表和返回类型的方法的引用。在计算器应用中,可以使用委托来定义事件处理程序,以及封装对方法的调用。 - 事件(Events):在C#中用于实现事件驱动编程,允许对象向订阅的客户端通知发生的事情。计算器可能会使用事件来反馈运算结果给用户界面。 - Lambda 函数:允许编写简洁的匿名方法,常用于事件处理器和回调函数中。在计算器项目中,lambda表达式可以用于简化事件的回调逻辑。 3. SOLID 编码实践: - 单一责任原则(Single Responsibility Principle):指的是一个类应该只有一个改变的理由,即一个类只负责一项任务。在计算器中,每个组件应只处理一个功能,如一个类专门处理输入,另一个类专门处理运算。 - 开闭原则(Open/Closed Principle):表示软件实体应该对扩展开放,但对修改封闭。计算器应用应当设计得足够灵活,以允许新的功能通过扩展来加入,而无需修改现有代码。 - 里氏替换原则(Liskov Substitution Principle):在计算器的上下文中,这意味着可以使用子类对象替代其父类对象,而不影响程序的正确性。例如,可以有一个抽象的数学操作类,子类可以是加法、减法操作等。 - 接口隔离原则(Interface Segregation Principle):表示不应强迫客户端依赖它们不使用的接口。计算器应该提供专用的接口,例如对于图形用户界面和命令行界面,它们可以有不同但更为专用的接口。 - 依赖倒置原则(Dependency Inversion Principle):核心思想是高层次的模块不应该依赖于低层次的模块,两者都应该依赖于抽象。计算器应用中,应避免直接依赖具体的实现类,而是通过依赖接口或抽象类。 4. 文件名称含义: - IS421Calc-C--main:很可能指的是C#语言编写的主程序文件。该文件可能包含了计算器应用程序的入口点(Main方法),以及程序的主要逻辑。 总结而言,IS421Calc-C-项目不仅是一个简单的控制台计算器,它还展示了如何在实际项目中运用设计模式和面向对象原则,以及C#编程语言的高级特性来构建健壮、可扩展的应用程序。通过对这些概念的学习和应用,开发者能够提高软件设计和代码质量,最终达到更好的软件维护性和扩展性。

我们要讨论一个关于计算光线追迹的程序,我会展示一些python代码,请从光学追迹的角度考虑其功能实现。 请详细解释以下python代码: ```python def create_cemented_doublet(power=0., bending=0., th=None, sd=1., glasses=('N-BK7,Schott', 'N-F2,Schott'), **kwargs): from opticalglass.spectral_lines import get_wavelength # type: ignore from opticalglass import util wvls = np.array([get_wavelength(w) for w in ['d', 'F', 'C']]) gla_a = gfact.create_glass(glasses[0]) rndx_a = gla_a.calc_rindex(wvls) Va, PcDa = util.calc_glass_constants(*rndx_a) gla_b = gfact.create_glass(glasses[1]) rndx_b = gla_b.calc_rindex(wvls) Vb, PcDb = util.calc_glass_constants(*rndx_b) power_a, power_b = achromat(power, Va, Vb) if th is None: th = sd/4 t1 = 3*th/4 t2 = th/4 if power_a < 0: t1, t2 = t2, t1 lens_a = lens_from_power(power=power_a, bending=bending, th=t1, sd=sd, med=gla_a) cv1, cv2, t1, indx_a, sd = lens_a # cv1 = power_a/(rndx_a[0] - 1) # delta_cv = -cv1/2 # cv1 += delta_cv # cv2 = delta_cv # cv3 = power_b/(1 - rndx_b[0]) + delta_cv indx_b = rndx_b[0] cv3 = (power_b/(indx_b-1) - cv2)/((t2*cv2*(indx_b-1)/indx_b) - 1) s1 = Surface(profile=Spherical(c=cv1), max_ap=sd, delta_n=(rndx_a[0] - 1)) s2 = Surface(profile=Spherical(c=cv2), max_ap=sd, delta_n=(rndx_b[0] - rndx_a[0])) s3 = Surface(profile=Spherical(c=cv3), max_ap=sd, delta_n=(1 - rndx_b[0])) g1 = Gap(t=t1, med=gla_a) g2 = Gap(t=t2, med=gla_b) g_tfrm = np.identity(3), np.array([0., 0., 0.]) ifc_list = [] ifc_list.append([0, s1, g1, 1, g_tfrm]) ifc_list.append([1, s2, g2, 1, g_tfrm]) ifc_list.append([2, s3, None, 1, g_tfrm]) ce = CementedElement(ifc_list) tree = ce.tree() return [[s1, g1, None, rndx_a, 1], [s2, g2, None, rndx_b, 1], [s3, None, None, 1, 1]], [ce], tree ```

2023-06-02 上传