jjzjj

java - 缺少的 "framework level"访问修饰符

coder 2024-03-14 原文

这是场景。作为公开许可的开源 API 的创建者,我的团队创建了一个基于 Java 的 Web 用户界面框架(那么还有什么新东西?)。为了保持 Java 中应有的良好和有条理,我们使用了具有命名约定的包 org.mygroup.myframework.x,其中 x 表示组件、 validator 、转换器、实用程序等(同样,还有什么是新的?)。

现在,类 org.mygroup.myframework.foo.Bar 中的某处是一个方法 void doStuff(),我需要执行特定于我的框架的逻辑,并且我需要能够调用它来 self 框架中的其他几个地方,例如 org.mygroup.myframework.far.Boo。鉴于 Boo 既不是 Bar 的子类也不在完全相同的包中,方法 doStuff() 必须声明为 public 才能被 Boo 调用。

但是,我的框架作为一种工具存在,允许其他开发人员为其客户创建更简单、更优雅的 R.I.A.。但是如果 com.yourcompany.yourapplication.YourComponent 调用 doStuff(),它可能会产生意想不到的不良后果。我会 宁愿这永远不会发生。 请注意,Bar 包含其他真正公开的方法。

在象牙塔世界中,我们将重写 Java 语言并插入一个标记化的默认访问模拟,这将允许我们选择的包结构中的任何类访问我的方法,可能看起来类似于:

[org.mygroup.myframework.*] void doStuff() { .... }

其中通配符表示任何包以 org.mygroup.myframework 开头的类都可以调用,但不能调用其他类。

如果这个世界不存在,我们还有什么其他好的选择?


请注意,这是受现实生活场景的启发;名称已更改以保护有罪的人。存在一个真正的框架,在它的 Javadoc 中到处都是,你会发现公共(public)方法被评论为“这个方法是 MYFRAMEWORK 的内部而不是 其公共(public) API 的一部分。 DO NOT CALL!!!!!!” 一些研究表明这些方法是从框架内的其他地方调用的。

事实上,我是一名使用上述框架的开发人员。虽然我们的应用程序已部署并取得成功,但我的团队经历了太多挑战,以至于我们想说服我们的老板再也不要使用这个框架。我们希望通过对框架开发人员做出的糟糕设计决策的深思熟虑的介绍来做到这一点,而不仅仅是咆哮。这个问题将是我们的(几个)观点之一,但我们无法确定我们如何以不同的方式完成它。在我的工作场所已经进行了一些热烈的讨论,所以我想知道世界其他地方会怎么想。


更新:到目前为止没有冒犯两位回答者,但我认为你没说对,或者我没有表达好。无论哪种方式,请允许我尝试阐明事物。尽可能简单地说,框架的开发人员应该如何重构以下内容。请注意,这是一个非常粗略的示例。

package org.mygroup.myframework.foo;
public class Bar {
     /** Adds a Bar component to application UI */
     public boolean addComponentHTML() {
         // Code that adds the HTML for a Bar component to a UI screen
         // returns true if successful
         // I need users of my framework to be able to call this method, so
         // they can actually add a Bar component to their application's UI
     }

     /** Not really public, do not call */
     public void doStuff() {
         // Code that performs internal logic to my framework
         // If other users call it, Really Bad Things could happen!
         // But I need it to be public so org.mygroup.myframework.far.Boo can call
     }
}

另一个更新:所以我刚刚了解到 C# 具有“内部”访问修饰符。因此,表达这个问题的更好方式可能是“如何在 Java 中模拟/模拟内部访问?”尽管如此,我并不是在寻找新的答案。我们的老板最终同意上述担忧

最佳答案

当您提到文档问题时,您最接近答案。真正的问题不在于您不能“保护”您的内部方法;相反,内部方法会污染您的文档并引入客户端模块可能错误调用内部方法的风险。

当然,即使您确实拥有细粒度的权限,您仍然无法阻止客户端模块调用内部方法——无论如何,jvm 无法防止基于反射的对私有(private)方法的调用.

我使用的方法是为每个有问题的类定义一个接口(interface),并让类实现它。该接口(interface)可以仅根据客户端模块进行记录,而实现类可以提供您想要的内部文档。如果您不想,您甚至不必在您的分发包中包含实现 javadoc,但无论哪种方式,边界都是明确划分的。

只要您确保在运行时每个文档接口(interface)只加载一个实现,现代 jvm 将保证您不会因使用它而遭受任何性能损失;并且,您可以在测试期间加载线束/ stub 版本以获得额外奖励。

关于java - 缺少的 "framework level"访问修饰符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10653919/

有关java - 缺少的 "framework level"访问修饰符的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  3. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  4. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  5. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  6. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  7. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  8. ruby-on-rails - 迷你测试错误 : "NameError: uninitialized constant" - 2

    我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test

  9. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  10. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

随机推荐