it-swarm-vi.tech

Cách làm phần mềm và phần mềm trong phần mềm trong Java là gì?

Tôi đã thấy những ví dụ như thế này:

public class MaxSeconds {
   public static final int MAX_SECONDS = 25;
}

và cho rằng tôi có thể có một lớp Hằng để bọc các hằng số, khai báo chúng là cuối cùng tĩnh. Tôi thực tế không biết Java chút nào và tự hỏi liệu đây có phải là cách tốt nhất để tạo các hằng.

373
mk.

Điều đó là hoàn toàn chấp nhận được, thậm chí có thể là tiêu chuẩn.

(public/private) static final TYPE NAME = VALUE;

trong đó TYPE là loại, NAME là tên trong tất cả các chữ hoa có dấu gạch dưới cho dấu cách và VALUE là giá trị không đổi;

Tôi đặc biệt khuyên KHÔNG nên đặt các hằng số của bạn trong các lớp hoặc giao diện riêng của chúng.

Như một lưu ý phụ: Các biến được tuyên bố là cuối cùng và có thể thay đổi vẫn có thể được thay đổi; tuy nhiên, biến không bao giờ có thể trỏ vào một đối tượng khác.

Ví dụ:

public static final Point Origin = new Point(0,0);

public static void main(String[] args){

    Origin.x = 3;

}

Đó là hợp pháp và Origin sau đó sẽ là một điểm tại (3, 0).

403
jjnguy

Tôi rất muốn khuyên không nên có một lớp hằng. Có vẻ như đó là một ý tưởng tốt vào thời điểm đó, nhưng khi các nhà phát triển từ chối ghi lại các hằng số và lớp phát triển để bao gồm hơn 500 hằng số không liên quan đến nhau (liên quan đến các khía cạnh hoàn toàn khác nhau của ứng dụng), điều này nói chung biến thành tệp hằng là hoàn toàn không thể đọc được. Thay thế:

  • Nếu bạn có quyền truy cập vào Java 5+, hãy sử dụng enum để xác định các hằng số cụ thể của bạn cho một khu vực ứng dụng. Tất cả các phần của khu vực ứng dụng nên tham chiếu đến enums, không phải giá trị không đổi, cho các hằng số này. Bạn có thể khai báo một enum tương tự như cách bạn khai báo một lớp. Enums có lẽ là tính năng hữu ích nhất (và, được cho là duy nhất) của Java 5+.
  • Nếu bạn có các hằng số chỉ hợp lệ với một lớp cụ thể hoặc một trong các lớp con của nó, hãy khai báo chúng là được bảo vệ hoặc công khai và đặt chúng lên lớp trên cùng trong hệ thống phân cấp. Theo cách này, các lớp con có thể truy cập các giá trị không đổi này (và nếu các lớp khác truy cập chúng thông qua công khai, các hằng số không chỉ hợp lệ với một lớp cụ thể ... có nghĩa là các lớp bên ngoài sử dụng hằng số này có thể được ghép quá chặt lớp chứa hằng số)
  • Nếu bạn có một giao diện với hành vi được xác định, nhưng các giá trị trả về hoặc giá trị đối số phải là đặc biệt, việc xác định các hằng số trên giao diện đó là hoàn toàn chấp nhận được để những người triển khai khác sẽ có quyền truy cập vào chúng. Tuy nhiên, tránh tạo giao diện chỉ để giữ các hằng số: nó có thể trở nên tồi tệ như một lớp được tạo chỉ để giữ các hằng số.
235
MetroidFan2002

Đó là một BAD PRACTICE để sử dụng các giao diện chỉ để giữ các hằng số (có tên mẫu giao diện không đổi của Josh Bloch). Đây là những gì Josh khuyên:

Nếu các hằng số được liên kết chặt chẽ với một lớp hoặc giao diện hiện có, bạn nên thêm chúng vào lớp hoặc giao diện. Ví dụ, tất cả các lớp nguyên thủy số được đóng hộp, chẳng hạn như Integer và Double, xuất các hằng số MIN_VALUE và MAX_VALUE. Nếu các hằng số được xem tốt nhất là thành viên của một kiểu liệt kê, bạn nên xuất chúng với loại enum. Nếu không, bạn nên xuất các hằng số với một lớp tiện ích không đáng kể.

Thí dụ:

// Constant utility class
package com.effectivejava.science;
public class PhysicalConstants {
    private PhysicalConstants() { }  // Prevents instantiation

    public static final double AVOGADROS_NUMBER   = 6.02214199e23;
    public static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
    public static final double ELECTRON_MASS      = 9.10938188e-31;
}

Về quy ước đặt tên:

Theo quy ước, các trường như vậy có tên bao gồm chữ in hoa, với các từ được phân tách bằng dấu gạch dưới. Điều quan trọng là các trường này chứa các giá trị nguyên thủy hoặc tham chiếu đến các đối tượng bất biến.

120
Marcio Aguiar

Trong Java hiệu quả (phiên bản 2), bạn nên sử dụng enum thay vì ints tĩnh cho các hằng số.

Có một bài viết hay về enums trong Java tại đây: http://Java.Sun.com/j2se/1.5.0/docs/guide/lingu/enums.html

Lưu ý rằng ở cuối bài viết đó, câu hỏi được đặt ra là:

Vậy khi nào bạn nên sử dụng enums?

Với câu trả lời là:

Bất cứ lúc nào bạn cần một bộ hằng số cố định

36
shelfoo

Chỉ cần tránh sử dụng một giao diện:

public interface MyConstants {
    String CONSTANT_ONE = "foo";
}

public class NeddsConstant implements MyConstants {

}

Nó là hấp dẫn, nhưng vi phạm đóng gói và làm mờ sự phân biệt của các định nghĩa lớp.

21
stimpy

Tôi sử dụng phương pháp sau:

public final class Constants {
  public final class File {
    public static final int MIN_ROWS = 1;
    public static final int MAX_ROWS = 1000;

    private File() {}
  }

  public final class DB {
    public static final String name = "oups";

    public final class Connection {
      public static final String URL = "jdbc:tra-ta-ta";
      public static final String USER = "testUser";
      public static final String PASSWORD = "testPassword";

      private Connection() {}
    }

    private DB() {}
  }

  private Constants() {}
}

Hơn, ví dụ, tôi sử dụng Constants.DB.Connection.URL để lấy hằng số. Nó trông "đối tượng" hơn đối với tôi.

19
albus.ua

Tạo các hằng số tĩnh cuối cùng trong một lớp riêng biệt có thể khiến bạn gặp rắc rối. Trình biên dịch Java sẽ thực sự tối ưu hóa điều này và đặt giá trị thực của hằng vào bất kỳ lớp nào tham chiếu nó.

Nếu sau này bạn thay đổi lớp 'Hằng số và bạn không biên dịch lại khó khăn cho các lớp khác tham chiếu lớp đó, bạn sẽ kết thúc với sự kết hợp của các giá trị cũ và mới được sử dụng.

Thay vì nghĩ về chúng như các hằng số, hãy nghĩ về chúng như các tham số cấu hình và tạo một lớp để quản lý chúng. Có các giá trị là không cuối cùng, và thậm chí xem xét sử dụng getters. Trong tương lai, khi bạn xác định rằng một số tham số này thực sự có thể được cấu hình bởi người dùng hoặc quản trị viên, điều đó sẽ dễ thực hiện hơn nhiều.

17
Kevin Day

Sai lầm số một bạn có thể mắc phải là tạo một lớp có thể truy cập toàn cầu được gọi bằng một tên chung, như Hằng số. Điều này chỉ đơn giản là bị vứt đầy rác và bạn mất hết khả năng để tìm ra phần nào trong hệ thống của bạn sử dụng các hằng số này.

Thay vào đó, hằng số nên vào lớp "sở hữu" chúng. Bạn có một hằng số được gọi là THỜI GIAN? Nó có lẽ nên đi vào lớp Communications () hoặc Connection () của bạn. MAX_BAD_LOGINS_PER_HOUR? Đi vào người dùng (). Vân vân và vân vân.

Việc sử dụng có thể khác là các tệp .properations Java khi "hằng số" có thể được xác định tại thời điểm chạy, nhưng người dùng không dễ dàng thay đổi. Bạn có thể gói chúng trong .jars của bạn và tham chiếu chúng với Class resourceLoader.

13
Yann Ramin

Đó là cách đúng đắn để đi.

Nói chung các hằng số là không được giữ trong các lớp "Hằng" riêng biệt vì chúng không thể khám phá được. Nếu hằng số có liên quan đến lớp hiện tại, việc giữ chúng ở đó sẽ giúp nhà phát triển tiếp theo.

6
Jason Cohen

Tôi đồng ý rằng sử dụng một giao diện không phải là cách để đi. Tránh mẫu này thậm chí còn có mục riêng (# 18) trong Bloch's Java hiệu quả .

Một đối số mà Bloch đưa ra đối với mẫu giao diện không đổi là việc sử dụng các hằng số là một chi tiết triển khai, nhưng việc thực hiện một giao diện để sử dụng chúng làm lộ chi tiết triển khai đó trong API xuất của bạn.

Mẫu public|private static final TYPE NAME = VALUE; là một cách tốt để khai báo hằng. Cá nhân, tôi nghĩ tốt hơn hết là tránh tạo một lớp riêng để chứa tất cả các hằng số của bạn, nhưng tôi chưa bao giờ thấy một lý do nào để không làm điều này, ngoài sở thích và phong cách cá nhân.

Nếu các hằng số của bạn có thể được mô hình hóa tốt như một bảng liệt kê, hãy xem xét cấu trúc enum có sẵn trong 1,5 hoặc sau đó.

Nếu bạn đang sử dụng một phiên bản sớm hơn 1,5, bạn vẫn có thể loại bỏ các liệt kê an toàn kiểu bằng cách sử dụng các lớp Java bình thường. (Xem trang này để biết thêm về điều đó).

5
Rob Dickerson

Điều gì về một bảng liệt kê?

5
Sébastien D.

Tôi thích sử dụng getters hơn là hằng số. Những getters có thể trả về giá trị không đổi, ví dụ: public int getMaxConnections() {return 10;}, nhưng bất cứ điều gì cần hằng sẽ đi qua một getter.

Một lợi ích là nếu chương trình của bạn vượt quá hằng số - bạn thấy rằng nó cần phải được cấu hình - bạn có thể thay đổi cách getter trả về hằng số.

Lợi ích khác là để sửa đổi hằng số, bạn không phải biên dịch lại mọi thứ sử dụng nó. Khi bạn tham chiếu trường cuối cùng tĩnh, giá trị của hằng số đó được biên dịch thành bất kỳ mã byte nào tham chiếu đến nó.

5
big_peanut_horse

Dựa trên các ý kiến ​​trên tôi nghĩ rằng đây là một cách tiếp cận tốt để thay đổi lớp hằng số toàn cầu kiểu cũ (có các biến cuối cùng tĩnh công khai) thành tương đương giống như enum của nó theo cách như sau:

public class Constants {

    private Constants() {
        throw new AssertionError();
    }

    public interface ConstantType {}

    public enum StringConstant implements ConstantType {
        DB_Host("localhost");
        // other String constants come here

        private String value;
        private StringConstant(String value) {
            this.value = value;
        }
        public String value() {
            return value;
        }
    }

    public enum IntConstant implements ConstantType {
        DB_PORT(3128), 
        MAX_PAGE_SIZE(100);
        // other int constants come here

        private int value;
        private IntConstant(int value) {
            this.value = value;
        }
        public int value() {
            return value;
        }
    }

    public enum SimpleConstant implements ConstantType {
        STATE_INIT,
        STATE_START,
        STATE_END;
    }

}

Vì vậy, sau đó tôi có thể giới thiệu họ thích:

Constants.StringConstant.DB_Host
4
Lorand Bendig

Một thiết kế hướng đối tượng tốt không cần nhiều hằng số có sẵn công khai. Hầu hết các hằng số nên được gói gọn trong lớp cần chúng để thực hiện công việc của nó.

3
Bradley Harris

Có một lượng ý kiến ​​nhất định để trả lời điều này. Để bắt đầu, các hằng số trong Java thường được khai báo là công khai, tĩnh và cuối cùng. Dưới đây là những lý do:

public, so that they are accessible from everywhere
static, so that they can be accessed without any instance. Since they are constants it
  makes little sense to duplicate them for every object.
final, since they should not be allowed to change

Tôi sẽ không bao giờ sử dụng một giao diện cho một bộ truy cập/đối tượng CONSTANTS đơn giản vì các giao diện thường được dự kiến ​​sẽ được thực hiện. Điều này sẽ không buồn cười:

String myConstant = IMyInterface.CONSTANTX;

Thay vào đó tôi sẽ chọn giữa một vài cách khác nhau, dựa trên một số sự đánh đổi nhỏ, và vì vậy nó phụ thuộc vào những gì bạn cần:

1.  Use a regular enum with a default/private constructor. Most people would define 
     constants this way, IMHO.
  - drawback: cannot effectively Javadoc each constant member
  - advantage: var members are implicitly public, static, and final
  - advantage: type-safe
  - provides "a limited constructor" in a special way that only takes args which match
     predefined 'public static final' keys, thus limiting what you can pass to the
     constructor

2.  Use a altered enum WITHOUT a constructor, having all variables defined with 
     prefixed 'public static final' .
  - looks funny just having a floating semi-colon in the code
  - advantage: you can JavaDoc each variable with an explanation
  - drawback: you still have to put explicit 'public static final' before each variable
  - drawback: not type-safe
  - no 'limited constructor'

3.  Use a Class with a private constructor:
  - advantage: you can JavaDoc each variable with an explanation
  - drawback: you have to put explicit 'public static final' before each variable
  - you have the option of having a constructor to create an instance
     of the class if you want to provide additional functions related
     to your constants 
     (or just keep the constructor private)
  - drawback: not type-safe

4. Using interface:
  - advantage: you can JavaDoc each variable with an explanation
  - advantage: var members are implicitly 'public static final'
  - you are able to define default interface methods if you want to provide additional
     functions related to your constants (only if you implement the interface)
  - drawback: not type-safe
2
djangofan

Cách tốt nhất để triển khai các hằng trong Java là gì?

Một cách tiếp cận mà chúng ta thực sự nên tránh: sử dụng giao diện để xác định các hằng số.

Tạo một giao diện cụ thể để khai báo các hằng số thực sự là điều tồi tệ nhất: nó đánh bại lý do tại sao các giao diện được thiết kế: xác định hợp đồng phương thức.

Ngay cả khi một giao diện đã tồn tại để giải quyết một nhu cầu cụ thể, việc khai báo các hằng số trong chúng thực sự không có ý nghĩa vì các hằng số không nên tạo ra một phần của API và hợp đồng được cung cấp cho các lớp máy khách.


Để đơn giản hóa, chúng tôi có 4 cách tiếp cận hợp lệ.

Với trường static final String/Integer:

  • 1) sử dụng một lớp khai báo các hằng số bên trong nhưng không chỉ.
  • 1 biến thể) tạo một lớp dành riêng cho chỉ khai báo hằng.

Với Java 5 enum:

  • 2) khai báo enum trong một lớp mục đích liên quan (vì vậy là một lớp lồng nhau).
  • 2 biến thể) tạo enum dưới dạng một lớp độc lập (được định nghĩa trong tệp lớp riêng của nó).

TLDR: Đó là cách tốt nhất và nơi xác định các hằng số?

Trong hầu hết các trường hợp, cách enum có lẽ tốt hơn cách static final String/Integer và cá nhân tôi nghĩ rằng chỉ nên sử dụng cách static final String/Integer nếu chúng ta có lý do chính đáng để không sử dụng enum.
[.__.] Và về nơi chúng ta nên khai báo các giá trị không đổi, ý tưởng là tìm kiếm xem có một lớp duy nhất nào sở hữu một sự gắn kết chức năng cụ thể và mạnh mẽ với các giá trị không đổi. Nếu chúng ta tìm thấy một lớp như vậy, chúng ta nên sử dụng nó như là người giữ hằng số. Mặt khác, hằng số phải được liên kết với không một lớp cụ thể nào.


static final String/static final Integer SO VỚI enum

Sử dụng Enums thực sự là một cách để xem xét mạnh mẽ.
[.__.] Enums có lợi thế lớn so với trường hằng số String hoặc Integer.
[.__.] Họ đặt ràng buộc biên dịch mạnh hơn. Nếu bạn định nghĩa một phương thức lấy enum làm tham số, bạn chỉ có thể truyền một giá trị enum được xác định trong lớp enum (hoặc null).
[.__.] Với Chuỗi và Số nguyên, bạn có thể thay thế chúng bằng bất kỳ giá trị nào thuộc loại tương thích và quá trình biên dịch sẽ ổn ngay cả khi giá trị không phải là hằng số xác định trong các trường static final String/static final Integer.

Ví dụ: bên dưới hai hằng số được xác định trong một lớp là các trường static final String:

public class MyClass{

   public static final String ONE_CONSTANT = "value";
   public static final String ANOTHER_CONSTANT = "other value";
   . . .
}

Đây là một phương thức dự kiến ​​sẽ có một trong các hằng số này làm tham số:

public void process(String constantExpected){
    ...    
}

Bạn có thể gọi nó theo cách này:

process(MyClass.ONE_CONSTANT);

hoặc là

process(MyClass.ANOTHER_CONSTANT);

Nhưng không có ràng buộc biên dịch nào ngăn bạn gọi nó theo cách này:

process("a not defined constant value");

Bạn sẽ chỉ có lỗi khi chạy và chỉ khi bạn thực hiện kiểm tra giá trị được truyền.

Với enum, không cần kiểm tra vì máy khách chỉ có thể chuyển giá trị enum trong tham số enum.

Ví dụ: ở đây có hai giá trị được xác định trong một lớp enum (không đổi trong hộp):

public enum MyEnum {

    ONE_CONSTANT("value"), ANOTHER_CONSTANT(" another value");

    private String value;

    MyEnum(String value) {
       this.value = value;
    }
         ...
}

Đây là một phương thức dự kiến ​​sẽ có một trong các giá trị enum này làm tham số:

public void process(MyEnum myEnum){
    ...    
}

Bạn có thể gọi nó theo cách này:

process(MyEnum.ONE_CONSTANT);

hoặc là

process(MyEnum.ANOTHER_CONSTANT);

Nhưng việc biên dịch sẽ không bao giờ cho phép bạn gọi nó theo cách này:

process("a not defined constant value");

Chúng ta nên khai báo các hằng số ở đâu?

Nếu ứng dụng của bạn chứa một lớp hiện có duy nhất sở hữu một sự gắn kết chức năng cụ thể và mạnh mẽ với các giá trị không đổi, thì 1) và 2) sẽ xuất hiện trực quan hơn.
[.__.] Nói chung, nó giúp giảm bớt việc sử dụng các hằng số nếu chúng được khai báo trong lớp chính thao túng chúng hoặc có một cái tên rất tự nhiên để đoán rằng chúng ta sẽ tìm thấy nó bên trong.

Ví dụ, trong thư viện JDK, các giá trị hằng số mũ và pi được khai báo trong một lớp khai báo không chỉ các khai báo hằng (Java.lang.Math).

   public final class Math {
          ...
       public static final double E = 2.7182818284590452354;
       public static final double PI = 3.14159265358979323846;
         ...
   }

Các máy khách sử dụng các hàm toán học thường dựa vào lớp Math. Vì vậy, họ có thể tìm thấy các hằng số đủ dễ dàng và cũng có thể nhớ nơi EPI được định nghĩa theo cách rất tự nhiên.

Nếu ứng dụng của bạn không chứa một lớp hiện có có sự gắn kết chức năng rất cụ thể và mạnh mẽ với các giá trị không đổi, thì các biến thể 1) và 2 biến thể) sẽ xuất hiện trực quan hơn.
[.__.] Nói chung, sẽ không dễ dàng sử dụng các hằng số nếu chúng được khai báo trong một lớp thao túng chúng trong khi chúng ta cũng có 3 hoặc 4 lớp khác thao túng chúng nhiều và dường như không có ai trong số các lớp này tự nhiên hơn những người khác để lưu trữ các giá trị không đổi.
[.__.] Ở đây, việc xác định một lớp tùy chỉnh chỉ giữ các giá trị không đổi có ý nghĩa.
[.__.] Ví dụ: trong thư viện JDK, enum Java.util.concurrent.TimeUnit không được khai báo trong một lớp cụ thể vì thực sự không có một và chỉ một lớp cụ thể JDK xuất hiện dưới dạng trực quan nhất để giữ nó:

public enum TimeUnit {
    NANOSECONDS {
      .....
    },
    MICROSECONDS {
      .....
    },
    MILLISECONDS {
      .....
    },
    SECONDS {
      .....
    },
      .....
}      

Nhiều lớp được khai báo trong Java.util.concurrent sử dụng chúng: BlockingQueue, ArrayBlockingQueue<E>, CompletableFuture, ExecutorService, ... và thực sự không ai trong số họ có vẻ thích hợp hơn để giữ enum.

2
davidxxx

FWIW, giá trị thời gian chờ tính bằng giây có lẽ phải là cài đặt cấu hình (đọc từ tệp thuộc tính hoặc thông qua tiêm như trong Spring) và không phải là hằng số.

1
Tim Howland

Sự khác biệt là gì

1.

public interface MyGlobalConstants {
    public static final int TIMEOUT_IN_SECS = 25;
}

2.

public class MyGlobalConstants {
    private MyGlobalConstants () {} // Prevents instantiation
    public static final int TIMEOUT_IN_SECS = 25;
}

và sử dụng MyGlobalConstants.TIMEOUT_IN_SECS bất cứ nơi nào chúng ta cần hằng số này. Tôi nghĩ cả hai đều giống nhau.

1
chandrayya

Một lớp hằng, chung là một ý tưởng tồi. Các hằng số nên được nhóm cùng với lớp mà chúng có liên quan logic nhất.

Thay vì sử dụng các biến của bất kỳ loại nào (đặc biệt là enums), tôi sẽ đề nghị bạn sử dụng các phương thức. Tạo một phương thức có cùng tên với biến và để nó trả về giá trị bạn đã gán cho biến đó. Bây giờ xóa biến và thay thế tất cả các tham chiếu đến nó bằng các lệnh gọi đến phương thức bạn vừa tạo. Nếu bạn cảm thấy rằng hằng là đủ chung chung mà bạn không cần phải tạo một thể hiện của lớp chỉ để sử dụng nó, thì hãy biến phương thức hằng thành phương thức lớp.

1
ab

Hằng số, thuộc bất kỳ loại nào, có thể được khai báo bằng cách tạo một thuộc tính bất biến trong một lớp (đó là biến thành viên có công cụ sửa đổi final). Thông thường, các bộ sửa đổi staticpublic cũng được cung cấp.

public class OfficePrinter {
    public static final String STATE = "Ready";  
}

Có rất nhiều ứng dụng trong đó giá trị của hằng số biểu thị lựa chọn từ n-Tuple (ví dụ: liệt kê) các lựa chọn. Trong ví dụ của chúng tôi, chúng tôi có thể chọn xác định Loại liệt kê sẽ hạn chế các giá trị được gán có thể (nghĩa là đã cải thiện loại an toàn):

public class OfficePrinter {
    public enum PrinterState { Ready, PCLoadLetter, OutOfToner, Offline };
    public static final PrinterState STATE = PrinterState.Ready;
}
1
Ryan Delucchi

Tôi sẽ không gọi lớp giống nhau (ngoài vỏ) là hằng số ... Tôi sẽ có tối thiểu một lớp "Cài đặt" hoặc "Giá trị" hoặc "Hằng số", nơi tất cả các hằng số sẽ sống. Nếu tôi có một số lượng lớn trong số họ, tôi sẽ nhóm chúng thành các lớp hằng số logic (Cài đặt người dùng, Cài đặt ứng dụng, v.v.)

0
Joel Martinez

static final là sở thích của tôi, tôi chỉ sử dụng enum nếu mục đó thực sự là vô số.

0
wulfgarpro

Đó là Thói quen BAD và thực hành ANNOYING khủng khiếp để trích dẫn Joshua Bloch mà không hiểu chủ nghĩa cơ bản cơ bản.

Tôi chưa đọc bất cứ điều gì Joshua Bloch, vì vậy hoặc

  • anh ấy là một lập trình viên tồi tệ
  • hoặc những người mà tôi tìm thấy trích dẫn anh ta (Joshua là tên của một cậu bé mà tôi đoán) chỉ đơn giản là sử dụng tài liệu của anh ta làm kịch bản tôn giáo để biện minh cho phần mềm tôn giáo của họ.

Như trong chủ nghĩa cơ bản Kinh Thánh, tất cả các luật kinh thánh có thể được tóm tắt bởi

  • Yêu bản sắc cơ bản với tất cả trái tim và tất cả tâm trí của bạn
  • Yêu hàng xóm như chính mình

và tương tự như vậy chủ nghĩa cơ bản kỹ thuật phần mềm có thể được tóm tắt bởi

  • cống hiến hết mình cho các nguyên tắc cơ bản bằng không với tất cả khả năng và tâm trí lập trình của bạn
  • và cống hiến cho sự xuất sắc của các lập trình viên của bạn như bạn làm cho chính mình.

Ngoài ra, trong số những người theo trào lưu chính thống trong Kinh thánh, một hệ quả mạnh mẽ và hợp lý được rút ra

  • Hãy yêu quý bản thân mình trước. Bởi vì nếu bạn không yêu bản thân mình nhiều, thì khái niệm "yêu người lân cận như chính mình" sẽ không mang nhiều sức nặng, vì "bạn yêu bản thân mình đến mức nào" là dòng chuẩn mực mà bạn sẽ yêu người khác.

Tương tự như vậy, nếu bạn không tôn trọng chính mình như một lập trình viên và chỉ chấp nhận những lời tuyên bố và lời tiên tri của một số bậc thầy lập trình mà KHÔNG đặt câu hỏi về các nguyên tắc cơ bản, thì những trích dẫn và sự phụ thuộc của bạn vào Joshua Bloch (và tương tự) là vô nghĩa. Và do đó, bạn thực sự sẽ không tôn trọng các lập trình viên của bạn.

Các định luật cơ bản của lập trình phần mềm

  • lười biếng là đức tính của một lập trình viên giỏi
  • bạn phải làm cho cuộc sống lập trình của bạn dễ dàng, lười biếng và do đó hiệu quả nhất có thể
  • bạn phải làm cho các hậu quả và các ràng buộc của chương trình của bạn trở nên dễ dàng, lười biếng và do đó hiệu quả nhất có thể đối với các lập trình viên neigbour của bạn, những người làm việc với bạn và nhận các ràng buộc lập trình của bạn.

Hằng số mô hình giao diện là một thói quen xấu ???

Theo luật nào về lập trình cơ bản có hiệu quả và có trách nhiệm thì sắc lệnh tôn giáo này rơi vào?

Chỉ cần đọc bài viết trên wikipedia về các hằng số mẫu giao diện ( https://en.wikipedia.org/wiki/Constant_interface ), và cái cớ ngớ ngẩn của nó chống lại các hằng số mẫu giao diện.

  • Whatif-Không có IDE? Ai trên trái đất là một lập trình viên phần mềm sẽ không sử dụng IDE? Hầu hết chúng ta là những lập trình viên, những người không muốn phải chứng minh rằng có chủ nghĩa sinh tồn vô căn cứ, tránh sử dụng IDE.

    • Ngoài ra - chờ một người đề xuất thứ hai về lập trình chức năng vi mô như một phương tiện không cần IDE. Đợi cho đến khi bạn đọc lời giải thích của tôi về chuẩn hóa mô hình dữ liệu.
  • Làm ô nhiễm không gian tên với các biến không được sử dụng trong phạm vi hiện tại? Nó có thể là những người ủng hộ ý kiến ​​này

    • không nhận thức được và sự cần thiết phải chuẩn hóa mô hình dữ liệu
  • Sử dụng các giao diện để thực thi các hằng số là lạm dụng các giao diện. Những người đề xuất như vậy có một thói quen xấu là

    • không thấy rằng "hằng số" phải được coi là hợp đồng. Và giao diện được sử dụng để thực thi hoặc dự kiến ​​tuân thủ hợp đồng.
  • Thật khó nếu không thể chuyển đổi giao diện thành các lớp được triển khai trong tương lai. Hả .... hừm ... ???

    • Tại sao bạn muốn tham gia vào mô hình lập trình như vậy là sinh kế bền bỉ của bạn? IOW, tại sao lại cống hiến hết mình cho một thói quen lập trình tồi tệ và tồi tệ như vậy?

Dù lý do là gì đi nữa, KHÔNG CÓ GIẢI QUYẾT GIÁ TRỊ khi nói đến kỹ thuật phần mềm HIỆU QUẢ HIỆU QUẢ để ủy thác hoặc nói chung không khuyến khích việc sử dụng các hằng giao diện.

Không có vấn đề gì về ý định ban đầu và trạng thái tinh thần của những người cha sáng lập đã xây dựng Hiến pháp Hoa Kỳ. Chúng ta có thể tranh luận về ý định ban đầu của những người sáng lập nhưng tất cả những gì tôi quan tâm là những tuyên bố bằng văn bản của Hiến pháp Hoa Kỳ. Và trách nhiệm của mỗi công dân Hoa Kỳ là khai thác chủ nghĩa văn học - chủ nghĩa cơ bản, chứ không phải là ý định sáng lập bất thành văn, của Hiến pháp Hoa Kỳ.

Tương tự, tôi không quan tâm ý định "nguyên bản" của những người sáng lập nền tảng Java và ngôn ngữ lập trình có gì cho giao diện. Điều tôi quan tâm là các tính năng hiệu quả mà đặc tả Java cung cấp và tôi dự định khai thác tối đa các tính năng đó để giúp tôi thực hiện các quy tắc cơ bản của lập trình phần mềm có trách nhiệm. Tôi không quan tâm nếu tôi bị coi là "vi phạm ý định cho giao diện". Tôi không quan tâm đến những gì mà Gosling hoặc ai đó Bloch nói về "cách sử dụng Java đúng đắn", trừ khi những gì họ nói không vi phạm nhu cầu của tôi để HIỆU QUẢ hoàn thành các nguyên tắc cơ bản.

Cơ bản là chuẩn hóa mô hình dữ liệu

Việc mô hình dữ liệu của bạn được lưu trữ hoặc truyền đi không quan trọng. Cho dù bạn sử dụng giao diện hay enum hay bất cứ thứ gì, quan hệ hay không có SQL, nếu bạn không hiểu nhu cầu và quy trình chuẩn hóa mô hình dữ liệu.

Trước tiên chúng ta phải xác định và chuẩn hóa mô hình dữ liệu của một tập hợp các quy trình. Và khi chúng ta có một mô hình dữ liệu mạch lạc, CHỈ sau đó chúng ta có thể sử dụng luồng quy trình của các thành phần của nó để xác định hành vi chức năng và xử lý chặn một trường hoặc lĩnh vực ứng dụng. Và chỉ sau đó chúng ta mới có thể xác định API của từng quy trình chức năng.

Ngay cả các khía cạnh của chuẩn hóa dữ liệu theo đề xuất của EF Codd hiện cũng bị thách thức nghiêm trọng và bị thách thức nghiêm trọng. ví dụ. tuyên bố của ông về 1NF đã bị chỉ trích là mơ hồ, sai lệch và đơn giản hóa, cũng như các tuyên bố còn lại của ông, đặc biệt là trong sự ra đời của các dịch vụ dữ liệu hiện đại, công nghệ repo và truyền dẫn. IMO, các câu lệnh Codd của EF phải được bỏ hoàn toàn và tập hợp các câu lệnh mới hợp lý hơn về mặt toán học được thiết kế.

Một lỗ hổng to lớn của EF Codd và nguyên nhân dẫn đến sự hiểu biết hiệu quả của con người là niềm tin của anh ta rằng dữ liệu đa chiều, có thể nhận biết được của con người có thể được cảm nhận một cách hiệu quả qua một tập hợp các ánh xạ 2 chiều.

Nguyên tắc cơ bản của chuẩn hóa dữ liệu

Những gì EF Codd không thể hiện.

Trong mỗi mô hình dữ liệu kết hợp, đây là thứ tự tốt nghiệp tuần tự của sự kết hợp mô hình dữ liệu để đạt được.

  1. Sự thống nhất và danh tính của các trường hợp dữ liệu. [.__.]
    • thiết kế độ chi tiết của từng thành phần dữ liệu, theo đó độ chi tiết của chúng ở mức độ mà mỗi thể hiện của một thành phần có thể được xác định và truy xuất duy nhất.
    • không có răng cưa tức là, không có phương tiện tồn tại theo đó một nhận dạng tạo ra nhiều hơn một thể hiện của một thành phần.
  2. Sự vắng mặt của nhiễu xuyên âm. Không tồn tại sự cần thiết phải sử dụng một hoặc nhiều phiên bản khác của một thành phần để góp phần xác định một thể hiện của một thành phần.
  3. Sự thống nhất và nhận dạng của các thành phần/kích thước dữ liệu. [.__.]
    • Sự hiện diện của khử răng cưa thành phần. Phải tồn tại một định nghĩa theo đó một thành phần/thứ nguyên có thể được xác định duy nhất. Đó là định nghĩa chính của một thành phần;
    • trong đó định nghĩa chính sẽ không dẫn đến việc phơi bày các thứ nguyên phụ hoặc thành phần thành viên không phải là một phần của thành phần dự định;
  4. Phương tiện độc đáo của thỏa thuận thành phần. Phải tồn tại một và chỉ một, định nghĩa khử răng cưa thành phần như vậy cho một thành phần.
  5. Tồn tại một và chỉ một giao diện định nghĩa hoặc hợp đồng để xác định một thành phần cha mẹ trong mối quan hệ phân cấp của các thành phần.
  6. Sự vắng mặt của xuyên âm thành phần. Không tồn tại sự cần thiết phải sử dụng một thành viên của một thành phần khác để góp phần xác định chính xác một thành phần. [.__.]
    • Trong mối quan hệ cha-con như vậy, định nghĩa xác định của cha mẹ không được phụ thuộc vào một phần của tập hợp các thành phần thành viên của trẻ. Thành phần thành viên trong danh tính của cha mẹ phải là danh tính con hoàn chỉnh mà không cần phải tham khảo bất kỳ hoặc tất cả con cái của một đứa trẻ.
  7. Ưu tiên xuất hiện hai phương thức hoặc đa phương thức của mô hình dữ liệu. [.__.]
    • Khi tồn tại hai định nghĩa ứng cử viên của một thành phần, đó là một dấu hiệu rõ ràng cho thấy tồn tại hai mô hình dữ liệu khác nhau được trộn lẫn thành một. Điều đó có nghĩa là có sự không phù hợp ở cấp mô hình dữ liệu hoặc cấp trường.
    • Một lĩnh vực ứng dụng phải sử dụng một và chỉ một mô hình dữ liệu, mạch lạc.
  8. Phát hiện và xác định đột biến thành phần. Trừ khi bạn đã thực hiện phân tích thành phần thống kê của dữ liệu khổng lồ, bạn có thể không thấy hoặc thấy sự cần thiết phải xử lý, đột biến thành phần. [.__.]
    • Một mô hình dữ liệu có thể có một số thành phần của nó biến đổi theo chu kỳ hoặc dần dần.
    • Chế độ có thể là xoay thành viên hoặc xoay chuyển vị.
    • Đột biến luân chuyển thành viên có thể là sự hoán đổi khác biệt giữa các thành phần con giữa các thành phần. Hoặc nơi mà các thành phần hoàn toàn mới sẽ phải được xác định.
    • Đột biến chuyển vị sẽ biểu hiện như một thành viên chiều biến đổi thành một thuộc tính, ngược lại.
    • Mỗi chu kỳ đột biến phải được xác định là một phương thức dữ liệu riêng biệt.
  9. Phiên bản hóa từng đột biến. Như vậy bạn có thể lấy ra một phiên bản trước của mô hình dữ liệu, khi có lẽ cần phải xử lý một đột biến 8 năm của mô hình dữ liệu.

Trong một trường hoặc lưới các ứng dụng thành phần liên dịch vụ, phải có một và chỉ một mô hình dữ liệu kết hợp hoặc tồn tại một phương tiện để mô hình dữ liệu/phiên bản nhận dạng chính nó.

Có phải chúng ta vẫn đang hỏi liệu chúng ta có thể sử dụng Giao diện không? Có thật không ?

Có những vấn đề bình thường hóa dữ liệu bị đe dọa nhiều hơn so với câu hỏi trần tục này. NẾU bạn không giải quyết được những vấn đề đó, sự nhầm lẫn mà bạn nghĩ rằng hằng số giao diện gây ra tương đối không có gì. Zilch.

Từ chuẩn hóa mô hình dữ liệu, sau đó bạn xác định các thành phần là biến, như thuộc tính, là hằng số giao diện hợp đồng.

Sau đó, bạn xác định đi vào giá trị tiêm, giữ chỗ cấu hình thuộc tính, giao diện, chuỗi cuối cùng, v.v.

Nếu bạn phải sử dụng lý do cần xác định vị trí một thành phần dễ dàng hơn để chống lại các hằng giao diện, điều đó có nghĩa là bạn đang có thói quen xấu là không thực hành chuẩn hóa mô hình dữ liệu.

Có lẽ bạn muốn biên dịch mô hình dữ liệu thành bản phát hành vcs. Rằng bạn có thể lấy ra một phiên bản có thể nhận dạng rõ ràng của mô hình dữ liệu.

Các giá trị được xác định trong các giao diện hoàn toàn được đảm bảo là không thể thay đổi. Và có thể chia sẻ. Tại sao tải một tập hợp các chuỗi cuối cùng vào lớp của bạn từ một lớp khác khi tất cả những gì bạn cần là tập các hằng đó ??

Vậy tại sao điều này không được công bố một hợp đồng mô hình dữ liệu? Ý tôi là nếu bạn có thể quản lý và bình thường hóa nó mạch lạc, tại sao không? ...

public interface CustomerService {
  public interface Label{
    char AssignmentCharacter = ':';
    public interface Address{
      String Street = "Street";
      String Unit= "Unit/Suite";
      String Municipal = "City";
      String County = "County";
      String Provincial = "State";
      String PostalCode = "Zip"
    }

    public interface Person {
      public interface NameParts{
        String Given = "First/Given name"
        String Auxiliary = "Middle initial"
        String Family = "Last name"
      }
    }
  }
}

Bây giờ tôi có thể tham chiếu các nhãn hợp đồng của ứng dụng của mình theo cách như

CustomerService.Label.Address.Street
CustomerService.Label.Person.NameParts.Family

Điều này gây nhầm lẫn nội dung của các tập tin jar? Là một lập trình viên Java, tôi không quan tâm đến cấu trúc của jar.

Điều này thể hiện sự phức tạp để hoán đổi thời gian chạy động cơ osgi? Osgi là một phương tiện cực kỳ hiệu quả để cho phép các lập trình viên tiếp tục thói quen xấu của họ. Có những lựa chọn thay thế tốt hơn osgi.

Hay tại sao không phải điều này? Không có sự rò rỉ của các Hằng riêng vào hợp đồng được công bố. Tất cả các hằng riêng nên được nhóm vào một giao diện riêng có tên là "Hằng", vì tôi không muốn phải tìm kiếm các hằng và tôi quá lười để gõ liên tục "Chuỗi cuối cùng riêng tư".

public class PurchaseRequest {
  private interface Constants{
    String INTERESTINGName = "Interesting Name";
    String OFFICIALLanguage = "Official Language"
    int MAXNames = 9;
  }
}

Có lẽ ngay cả điều này:

public interface PurchaseOrderConstants {
  public interface Properties{
    default String InterestingName(){
       return something();
    }
    String OFFICIALLanguage = "Official Language"
    int MAXNames = 9;
  }
}

Vấn đề duy nhất với các hằng số giao diện đáng xem xét là khi giao diện được triển khai.

Đây không phải là "ý định ban đầu" của giao diện? Giống như tôi sẽ quan tâm đến "ý định ban đầu" của những người sáng lập trong việc xây dựng Hiến pháp Hoa Kỳ, thay vì Tòa án Tối cao sẽ diễn giải các văn bản của Hiến pháp Hoa Kỳ như thế nào ???

Rốt cuộc, tôi sống ở vùng đất tự do, hoang dã và quê hương của những người dũng cảm. Hãy dũng cảm, tự do, tự nhiên - sử dụng giao diện. Nếu các lập trình viên đồng nghiệp của tôi từ chối sử dụng các phương tiện lập trình hiệu quả và lười biếng, tôi có bị ràng buộc bởi quy tắc vàng để giảm hiệu quả lập trình của mình để phù hợp với họ không? Có lẽ tôi nên, nhưng đó không phải là một tình huống lý tưởng.

0
Blessed Geek

Để tiến thêm một bước, bạn có thể đặt các hằng số được sử dụng toàn cầu trong một giao diện để chúng có thể được sử dụng trên toàn hệ thống. Ví dụ.

public interface MyGlobalConstants {
    public static final int TIMEOUT_IN_SECS = 25;
}

Nhưng đừng thực hiện nó. Chỉ cần tham khảo chúng trực tiếp trong mã thông qua tên lớp đủ điều kiện.

0
Andrew Harmel-Law

Tôi sử dụng static final để khai báo các hằng số và đi với ký hiệu đặt tên ALL_CAPS. Tôi đã thấy khá nhiều trường hợp thực tế trong đó tất cả các hằng số được tập hợp lại thành một giao diện. Một vài bài đăng đã gọi đúng đó là một thực tiễn tồi, chủ yếu là vì đó không phải là giao diện dành cho. Một giao diện nên thực thi hợp đồng và không nên là nơi đặt các hằng số không liên quan. Đặt nó cùng nhau vào một lớp không thể khởi tạo (thông qua một hàm tạo riêng) cũng không sao nếu ngữ nghĩa không đổi không thuộc về một lớp cụ thể ( es). Tôi luôn đặt một hằng số trong lớp mà nó liên quan nhiều nhất, bởi vì điều đó có ý nghĩa và cũng dễ dàng duy trì.

Enums là một lựa chọn tốt để biểu thị một phạm vi các giá trị, nhưng nếu bạn đang lưu trữ các hằng số độc lập với sự nhấn mạnh vào giá trị tuyệt đối (ví dụ: TIMEOUT = 100 ms), bạn có thể chỉ cần sử dụng phương pháp static final.

0
bincob

Đối với Hằng, Enum là một lựa chọn tốt hơn IMHO. Đây là một ví dụ

public class myClass {

public enum myEnum {
    Option1("String1", 2), 
    Option2("String2", 2) 
    ;
    String str;
            int i;

            myEnum(String str1, int i1) { this.str = str1 ; this.i1 = i }


}
0
mmansoor

Tôi đồng ý với những gì hầu hết đang nói, tốt nhất là sử dụng enum khi xử lý một bộ sưu tập các hằng số. Tuy nhiên, nếu bạn đang lập trình trong Android, có một giải pháp tốt hơn: Chú thích IntDef .

@Retention(SOURCE)
@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST,NAVIGATION_MODE_TABS})
public @interface NavigationMode {}
public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;
...
public abstract void setNavigationMode(@NavigationMode int mode);
@NavigationMode
public abstract int getNavigationMode();

Chú thích IntDef vượt trội hơn so với enums theo một cách đơn giản, nó chiếm ít không gian hơn đáng kể vì nó chỉ đơn giản là một điểm đánh dấu thời gian biên dịch. Nó không phải là một lớp, nó cũng không có thuộc tính chuyển đổi chuỗi tự động.

0
Quinn Turner

Một trong những cách tôi làm là bằng cách tạo một lớp 'Toàn cầu' với các giá trị không đổi và thực hiện nhập tĩnh trong các lớp cần truy cập vào hằng.

0
Javamann