组织Java常量的理想方法

时间:2012-02-28 16:04:46

标签: java coding-style constants code-organization

我们有一个基于旧的jdk 1.4的大型项目。我们已将Web应用程序迁移到JDK 1.6,但代码中仍然存在大量低效的实践和糟糕的设计。

关于主要的痛点点巨大的java类在单个java文件中有2500多行代码。这么多文件都是这样的。

尝试通过删除常量并将常量放在不同的Constants.java文件中来重构我开始的类。但由于整个应用程序中有很多常量,因此常量文件存在增长到巨大比例的风险。

我希望得到关于开发人员采用什么策略来保持代码清洁和可维护的反馈。

8 个答案:

答案 0 :(得分:16)

将你的常数保持在他们所关联的类中,不觉得有必要提取它们。它可能会清理类的代码,但在文件中混合不相关的常量并不是一种改进。

保持相关的内容

此外,您可以在可能/有用的情况下将它们转换为枚举(但这可能需要进行一些重构)。

答案 1 :(得分:13)

将所有常量放在一个文件中是个糟糕的主意!尤其是超级常数反模式,其中所有常量都在Interface中,每个类都必须implement。周日可怕的10种方式!当人们在Java之前的1990年代早期开始做这件事时,这是一个坏主意!这在2012年绝对是一个坏主意!

这意味着每次导入此uber-Constants文件时,您都会混合大量不相关的信息并创建不需要的依赖项。合在一起的东西应该放在Enum或至少Class中,它们将它们用作其方法的参数,这样当它们被更改时,您就知道如何轻松地进行影响分析。

想象Color常量与其他业务域常量混合的DaysOfTheWeek常量混合在一起,单个文件中将有数百个(如果不是数千个)这些东西。怎么能被认为是个好主意?在每个非人为的情况下,Enum成为public inner成员的Class是更好的解决方案。

这也意味着您有一个单独的平面命名空间来尝试创建不冲突的名称,然后它们并不明显它们属于什么以及应该如何使用它们。这绝不是一个积极的练习。

在进行设计和重构时,您应始终:

努力争取高凝聚力,这意味着尽可能将相关事物保持在一起。

争取松散耦合这意味着不要让不相关的事情泄漏到其他不相关的范围内。

努力实现自我记录的可维护代码,所有混合在一起的数十个或数百个private static final String/int声明不符合任何人的标准!

2012年,当您使用Enum作为工具时,C风格常量是一个糟糕的解决方案,您应该专注于尽可能多地将这些常量组转换为EnumEnum是类型安全的,可以附加其他属性和属性以及行为intelligent。这是走下去的道路。

答案 2 :(得分:2)

将常量放在Constant.java文件中并不会让我觉得敏感(它只是将问题移开)。但有时我会重新组合它们以清除事物并使用几个文件重新组合它们:DatabaseConstants.javaGraphicConstants.java等等...... 当然,使用枚举也很有用(和最佳实践)。

编辑:确切地说,我实际上使用的是Java ME应用程序,因此它只是一种“模仿”我不能拥有的枚举的方法,在抽象类中使用“受控词汇表”(我想念所有Java EE)功能...)

答案 3 :(得分:1)

正在访问此页面的人。

如果您不想维护多个常量文件,则下面是更好的组织方式。

public interface Constants {
    public static final String CREATE_USER = "createUser";
    // Nested Interface.
    public interface ProjectConstants {
        public static final String CREATE_PROJECT = "createProject";
        public static final String INVALID_SESSION = "Invalid Session";
        // As you know they are implicity public static final.
    }
}// Accessed as: 
Constants.ProjectConstants.CREATE_PROJECT

更新

作为最佳实践,最好使用Class。(参见评论。感谢keplerian。)

public final class Constants {

    private Constants() {
        // restrict instantiation
    }

    public static final double PI = 3.14159;
    public static final double PLANCK_CONSTANT = 6.62606896e-34;
}

import static Constants.PLANCK_CONSTANT;
import static Constants.PI;

public class Calculations {

    public double getReducedPlanckConstant() {
        return PLANCK_CONSTANT / (2 * PI);
    }
}

答案 4 :(得分:1)

我想分享几年前我见过的常数的设计模式,可能有所帮助。

首先创建一个BaseConstant文件。这将包含所有包可以使用的所有全局常量。

现在,在应用程序的每个子包中,创建一个仅与子包相关的Constants文件。所以,如果你有。一个名为Login的子包只放置与登录相关的常量。但关键是要扩展BaseConstants。这样你就可以看到IDE选择器中的所有全局常量,但是当你打开文件时,你只能看到你的包常量。据说我认为常量文件可能会变得非常繁重并且重复值并且难以阅读。

这就是我的意思..

    public class BingMapFragment extends Fragment {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    private View main_view;

    private  static View v;
    private WebView webMapView;
    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;
    ListView lv;
    TraceAdapter aAdpt;
    private  FragmentChangeActivity parent;

    private OnFragmentInteractionListener mListener;

    public BingMapFragment() {
        // Required empty public constructor
         setRetainInstance(true);
    }



    // TODO: Rename and change types and number of parameters
    public static BingMapFragment newInstance(String param1, String param2) {
        BingMapFragment fragment = new BingMapFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);

            webMapView = (WebView)main_view.findViewById(R.id.bingMapView);
            webMapView.setWebViewClient(new WebViewClient());

            WebSettings ws = webMapView.getSettings();
            ws.setJavaScriptEnabled(true);
            webMapView.loadUrl("file:///android_asset/prova.html");




        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        new DataSourceDeviceRealTime().getDeviceRealTime(this);
        main_view = inflater.inflate(R.layout.fragment_bing_map,container,false); 
        v=main_view;
        parent=(FragmentChangeActivity) getActivity();
        parent.setupActionBar(Constants.SCREEN_MAP);




    return inflater.inflate(R.layout.fragment_bing_map, container, false);

    }

    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }


    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);
    }

    public void goBack() {
        if(GlobalData.isSalesforcePolicyActive() ||  GlobalData.isMobileRoutePolicyActive()){
            parent.switchContent(new MenuFragment(), true);
        } else {
            parent.logoutButtonClicked(); 
        }
        }
    }

现在在所有其他包中创建如下文件:

public class BaseConstants{

public static final String GLOBAL1= "GLOBAL string"; 

public static final String GLOBAL2= "another GLOBAL string"; 
}
键入“MyPackageConstants”时,在IDE中

。你应该看到整个应用程序的所有常量。

答案 5 :(得分:0)

我从未听说过将所有常量都放在一个java文件中。最好的方法是将常量与类本身相对应,但是用大写字母和下划线命名它们,如下所示:EXAMPLE_CONSTANT

答案 6 :(得分:0)

您是否尝试过为所有常量使用枚举?我被告知这是自Java 1.5以来的首选方式。

http://docs.oracle.com/javase/1.5.0/docs/guide/language/enums.html

答案 7 :(得分:-1)

我认为如果你有超过2500个LOC的多个java文件,决定放置常量的位置应该是你问题中最少的。您应该清楚地了解重组系统的外观。 这可能比决定在哪里坚持常数和其他句法考虑因素要困难得多,但仍然需要首先完成。