উত্তর:
এনামগুলিকে কেবল প্যাসিভ সেট (যেমন রঙ) উপস্থাপন করতে হবে না। এগুলি কার্যকারিতা সহ আরও জটিল বস্তুগুলির প্রতিনিধিত্ব করতে পারে এবং তাই আপনি এরপরে আরও কার্যকারিতা যুক্ত করতে চান - যেমন আপনার ইন্টারফেসগুলি থাকতে পারে Printable
, Reportable
ইত্যাদি এবং উপাদানগুলি সমর্থন করে এমন উপাদানগুলি।
এখানে একটি উদাহরণ (কার্যকর জাভা দ্বিতীয় সংস্করণে অনুরূপ / আরও ভাল একটি পাওয়া যায়):
public interface Operator {
int apply (int a, int b);
}
public enum SimpleOperators implements Operator {
PLUS {
int apply(int a, int b) { return a + b; }
},
MINUS {
int apply(int a, int b) { return a - b; }
};
}
public enum ComplexOperators implements Operator {
// can't think of an example right now :-/
}
এখন সাধারণ + কমপ্লেক্স অপারেটর উভয়ের একটি তালিকা পেতে:
List<Operator> operators = new ArrayList<Operator>();
operators.addAll(Arrays.asList(SimpleOperators.values()));
operators.addAll(Arrays.asList(ComplexOperators.values()));
সুতরাং এখানে আপনি এক্সটেনসিবল এনামগুলিকে অনুকরণ করতে একটি ইন্টারফেস ব্যবহার করেন (যা কোনও ইন্টারফেস ব্যবহার না করে সম্ভব হবে না)।
Comparable
উদাহরণস্বরূপ কয়েক জনের কর্তৃক প্রদত্ত এখানে ভুল, যেহেতু Enum
ইতিমধ্যে কার্যকরী হয়। আপনি এটি ওভাররাইডও করতে পারবেন না।
এর চেয়ে আরও ভাল উদাহরণের মধ্যে একটি ইন্টারফেস রয়েছে যা সংজ্ঞায়িত করে, যাক, একটি ডেটা টাইপ। সাধারণ প্রকারগুলি কার্যকর করতে আপনার একটি এনাম থাকতে পারে এবং জটিল ধরণের প্রয়োগের জন্য সাধারণ ক্লাস থাকতে পারে:
interface DataType {
// methods here
}
enum SimpleDataType implements DataType {
INTEGER, STRING;
// implement methods
}
class IdentifierDataType implements DataType {
// implement interface and maybe add more specific methods
}
আমি প্রায়শই ব্যবহার করি এমন একটি মামলা রয়েছে। IdUtil
খুব সাধারণ Identifiable
ইন্টারফেস প্রয়োগকারী অবজেক্টের সাথে কাজ করার জন্য আমার স্ট্যাটিক পদ্ধতি সহ একটি বর্গ রয়েছে :
public interface Identifiable<K> {
K getId();
}
public abstract class IdUtil {
public static <T extends Enum<T> & Identifiable<S>, S> T get(Class<T> type, S id) {
for (T t : type.getEnumConstants()) {
if (Util.equals(t.getId(), id)) {
return t;
}
}
return null;
}
public static <T extends Enum<T> & Identifiable<S>, S extends Comparable<? super S>> List<T> getLower(T en) {
List<T> list = new ArrayList<>();
for (T t : en.getDeclaringClass().getEnumConstants()) {
if (t.getId().compareTo(en.getId()) < 0) {
list.add(t);
}
}
return list;
}
}
যদি আমি এটি তৈরি করি Identifiable
enum
:
public enum MyEnum implements Identifiable<Integer> {
FIRST(1), SECOND(2);
private int id;
private MyEnum(int id) {
this.id = id;
}
public Integer getId() {
return id;
}
}
তারপরে আমি এটি id
এইভাবে এটি পেতে পারি :
MyEnum e = IdUtil.get(MyEnum.class, 1);
যেহেতু এনামগুলি ইন্টারফেস প্রয়োগ করতে পারে সেগুলি সিঙ্গলটন নিদর্শনটির কঠোর প্রয়োগের জন্য ব্যবহার করা যেতে পারে। একটি স্ট্যান্ডার্ড ক্লাস করার চেষ্টা করে সিঙ্গলটন অনুমতি দেয় ...
এনলেটস হিসাবে সিলেটলেট এই সুরক্ষা সমস্যাগুলি রোধ করতে সহায়তা করে। এনামদের ক্লাস হিসাবে কাজ করতে এবং ইন্টারফেস প্রয়োগ করতে এটি অবদান রাখার অন্যতম কারণ হতে পারে। শুধু অনুমান।
দেখুন /programming/427902/java-enum-singleton এবং জাভা একক বর্গ আরো আলোচনার জন্য।
for inheriting from your singleton and overriding your singleton's methods with something else
। এটি final class
রোধ করতে আপনি কেবল একটি ব্যবহার করতে পারেন
এটি এক্সটেনসিবিলিটির জন্য প্রয়োজনীয় - যদি কেউ আপনার বিকাশকৃত একটি এপিআই ব্যবহার করে তবে আপনার সংজ্ঞায়িত এনামগুলি স্থির; এগুলিতে যোগ বা পরিবর্তন করা যায় না। তবে, আপনি যদি এটি কোনও ইন্টারফেস প্রয়োগ করতে দেন তবে এপিআই ব্যবহার করা ব্যক্তি একই ইন্টারফেস ব্যবহার করে তাদের নিজস্ব এনাম বিকাশ করতে পারে। তারপরে আপনি এই এনামকে এনাম ম্যানেজারের সাথে নিবন্ধভুক্ত করতে পারবেন যা মানচিত্রটির সাথে ইন্টারফেসের সাথে একত্রে এনামগুলিকে একত্রিত করে।
সম্পাদনা করুন: @ হেল্পার পদ্ধতির এটির নিখুঁত উদাহরণ রয়েছে। নতুন অপারেটরগুলি সংজ্ঞায়িত করে এবং তারপরে কোনও ম্যানেজার শ্রেণিকে বলার অপেক্ষা রাখে যে 'আরে, এই এনাম রয়েছে - এটি রেজিস্টার করুন'। অন্যথায়, আপনি কেবল নিজের কোডে অপারেটরগুলি সংজ্ঞায়িত করতে সক্ষম হবেন - কোনও প্রসারিততা থাকবে না।
এনামগুলি ছদ্মবেশে কেবল ক্লাস হয় তাই বেশিরভাগ অংশের জন্য, আপনি এনামের সাথে ক্লাসের সাথে যা কিছু করতে পারেন।
আমি কোনও কারণ ভাবতে পারি না যে কোনও এনাম কোনও ইন্টারফেস কার্যকর করতে সক্ষম না হওয়া উচিত, একই সাথে আমি তাদের উভয়ের পক্ষে কোনও ভাল কারণও ভাবতে পারি না।
আমি একবার বলব আপনি একবার ইন্টারফেসের মতো জিনিস যুক্ত করতে শুরু করলেন বা এনামের সাথে পদ্ধতিতে আপনার পরিবর্তে এটি একটি শ্রেণিবদ্ধ করা বিবেচনা করা উচিত। অবশ্যই আমি নিশ্চিত যে অপ্রথাগত এনাম জিনিসগুলি করার জন্য বৈধ মামলা রয়েছে, এবং যেহেতু সীমাটি একটি কৃত্রিম হবে, তাই আমি লোকদের সেখানে যা করতে চাইবে তা দেওয়ার পক্ষে।
এর জন্য সর্বাধিক সাধারণ ব্যবহার হ'ল দুটি এনামের মানগুলিকে এক দলে একীভূত করা এবং তাদের সাথে একইভাবে আচরণ করা। উদাহরণস্বরূপ, ফল এবং Vegatables কীভাবে যোগদান করবেন তা দেখুন ।
ইন্টারফেসের সাথে এনাম ব্যবহার করার জন্য আমার পক্ষে সেরা ব্যবহারের একটি হ'ল প্রিডিকেট ফিল্টার। এটি অ্যাপাচি সংগ্রহের টাইপিংয়ের অভাব প্রতিকার করার খুব মার্জিত উপায় (যদি অন্য গ্রন্থাগারগুলি ব্যবহার নাও করা যায়)।
import java.util.ArrayList;
import java.util.Collection;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
public class Test {
public final static String DEFAULT_COMPONENT = "Default";
enum FilterTest implements Predicate {
Active(false) {
@Override
boolean eval(Test test) {
return test.active;
}
},
DefaultComponent(true) {
@Override
boolean eval(Test test) {
return DEFAULT_COMPONENT.equals(test.component);
}
}
;
private boolean defaultValue;
private FilterTest(boolean defautValue) {
this.defaultValue = defautValue;
}
abstract boolean eval(Test test);
public boolean evaluate(Object o) {
if (o instanceof Test) {
return eval((Test)o);
}
return defaultValue;
}
}
private boolean active = true;
private String component = DEFAULT_COMPONENT;
public static void main(String[] args) {
Collection<Test> tests = new ArrayList<Test>();
tests.add(new Test());
CollectionUtils.filter(tests, FilterTest.Active);
}
}
উল্লিখিত কৌশলগুলি উপরের পোস্টটি এনামগুলি ব্যবহার করে কৌশল প্যাটার্নটির একটি সুন্দর হালকা ওজনের বাস্তবায়ন আপনাকে যথেষ্ট পরিমাণে চাপ দেয়নি:
public enum Strategy {
A {
@Override
void execute() {
System.out.print("Executing strategy A");
}
},
B {
@Override
void execute() {
System.out.print("Executing strategy B");
}
};
abstract void execute();
}
প্রত্যেকের জন্য পৃথক সংকলন ইউনিটের প্রয়োজন ছাড়াই আপনার সমস্ত কৌশল এক জায়গায় থাকতে পারে। আপনি ঠিক এর সাথে একটি দুর্দান্ত গতিশীল প্রেরণা পান:
Strategy.valueOf("A").execute();
জাভা প্রায় একটি দুর্দান্ত lyিলে !ালা টাইপের ভাষার মতো পড়ায়!
এনামগুলি জাভা ক্লাসগুলির মতো হয়, তাদের কাছে কনস্ট্রাক্টর, পদ্ধতি ইত্যাদি থাকতে পারে আপনি কেবল তাদের সাথে না করতে পারেন new EnumName()
। উদাহরণগুলি আপনার এনাম ঘোষণায় পূর্বনির্ধারিত।
enum Foo extends SomeOtherClass
? একটি নিয়মিত ক্লাস হিসাবে তাই একই জিনিস না, আসলে, বেশ ভিন্ন।
আরেকটি সার্থকতা:
public enum ConditionsToBeSatisfied implements Predicate<Number> {
IS_NOT_NULL(Objects::nonNull, "Item is null"),
IS_NOT_AN_INTEGER(item -> item instanceof Integer, "Item is not an integer"),
IS_POSITIVE(item -> item instanceof Integer && (Integer) item > 0, "Item is negative");
private final Predicate<Number> predicate;
private final String notSatisfiedLogMessage;
ConditionsToBeSatisfied(final Predicate<Number> predicate, final String notSatisfiedLogMessage) {
this.predicate = predicate;
this.notSatisfiedLogMessage = notSatisfiedLogMessage;
}
@Override
public boolean test(final Number item) {
final boolean isNotValid = predicate.negate().test(item);
if (isNotValid) {
log.warn("Invalid {}. Cause: {}", item, notSatisfiedLogMessage);
}
return predicate.test(item);
}
}
এবং ব্যবহার:
Predicate<Number> p = IS_NOT_NULL.and(IS_NOT_AN_INTEGER).and(IS_POSITIVE);
একটি জার ফাইলে ধ্রুবক তৈরি করার সময়, ব্যবহারকারীদের এনাম মানগুলি বাড়িয়ে দেওয়া প্রায়শই সহায়ক। আমরা প্রপার্টিফাইল কীগুলির জন্য এনাম ব্যবহার করেছি এবং আটকে গেলাম কারণ কেউই কোনও নতুন যুক্ত করতে পারে নি! নীচে আরও ভাল কাজ করতে হবে।
প্রদত্ত:
public interface Color {
String fetchName();
}
এবং:
public class MarkTest {
public static void main(String[] args) {
MarkTest.showColor(Colors.BLUE);
MarkTest.showColor(MyColors.BROWN);
}
private static void showColor(Color c) {
System.out.println(c.fetchName());
}
}
একটি জার মধ্যে একটি এনাম থাকতে পারে:
public enum Colors implements Color {
BLUE, RED, GREEN;
@Override
public String fetchName() {
return this.name();
}
}
এবং কোনও ব্যবহারকারী তার নিজস্ব রঙ যুক্ত করতে এটি প্রসারিত করতে পারে:
public enum MyColors implements Color {
BROWN, GREEN, YELLOW;
@Override
public String fetchName() {
return this.name();
}
}
আমার কারণ এখানে ...
আমি একটি এনামের মান সহ একটি জাভাএফএক্স কম্বোবক্সকে জনপ্রিয় করেছি। আমার একটি ইন্টারফেস রয়েছে, শনাক্তকরণযোগ্য (একটি পদ্ধতি নির্দিষ্ট করে: সনাক্তকরণ), যা আমাকে নির্দিষ্ট করার অনুমতি দেয় যে কীভাবে কোনও বিষয় অনুসন্ধানের উদ্দেশ্যে আমার অ্যাপ্লিকেশনটিতে নিজেকে চিহ্নিত করে। এই ইন্টারফেসটি আমাকে কোনও পরিচয় ম্যাচের জন্য যেকোন ধরণের অবজেক্টের (যে ক্ষেত্রের ক্ষেত্রে বস্তুটি পরিচয়ের জন্য ব্যবহার করতে পারে) তালিকা স্ক্যান করতে সক্ষম করে।
আমি আমার কম্বোবক্স তালিকায় একটি পরিচয় মানের জন্য একটি মিল খুঁজে পেতে চাই। এনাম মানযুক্ত আমার কম্বোবক্সে এই ক্ষমতাটি ব্যবহার করার জন্য, অবশ্যই আমার এনুমে সনাক্তকরণযোগ্য ইন্টারফেসটি প্রয়োগ করতে সক্ষম হব (যা এটি ঘটে যেমন একটি এনামের ক্ষেত্রে প্রয়োগ করার জন্য তুচ্ছ)।
আমি একটি ইন্টারফেসে একটি অভ্যন্তরীণ এনাম ব্যবহার করেছি সেখান থেকে উদাহরণ নিয়ন্ত্রণ রাখতে প্রতিটি কৌশল (প্রতিটি কৌশলই সিঙ্গলটন)।
public interface VectorizeStrategy {
/**
* Keep instance control from here.
*
* Concrete classes constructors should be package private.
*/
enum ConcreteStrategy implements VectorizeStrategy {
DEFAULT (new VectorizeImpl());
private final VectorizeStrategy INSTANCE;
ConcreteStrategy(VectorizeStrategy concreteStrategy) {
INSTANCE = concreteStrategy;
}
@Override
public VectorImageGridIntersections processImage(MarvinImage img) {
return INSTANCE.processImage(img);
}
}
/**
* Should perform edge Detection in order to have lines, that can be vectorized.
*
* @param img An Image suitable for edge detection.
*
* @return the VectorImageGridIntersections representing img's vectors
* intersections with the grids.
*/
VectorImageGridIntersections processImage(MarvinImage img);
}
এনাম এই কৌশলটি প্রয়োগ করে তা এনাম শ্রেণিকে তার বদ্ধ দৃষ্টান্তের জন্য প্রক্সি হিসাবে কাজ করার অনুমতি দেওয়ার পক্ষে সুবিধাজনক। যা ইন্টারফেস প্রয়োগ করে।
এটি এক ধরণের কৌশল এনামপ্রক্সি: পি ক্লেন্ট কোডটি দেখতে এই রকম:
VectorizeStrategy.ConcreteStrategy.DEFAULT.processImage(img);
যদি এটি ইন্টারফেসটি বাস্তবায়ন না করে তবে এটি করা হত:
VectorizeStrategy.ConcreteStrategy.DEFAULT.getInstance().processImage(img);