Library Management System Java

0 views
Skip to first unread message

Lourdes Horace

unread,
Aug 3, 2024, 1:47:12 PM8/3/24
to liadimamust

I have to build a library management system and i've run into problems while trying to implement user types or profiles. I've already got a superclass user and two other subclasses of User, Student and Teacher, each with their own "characteristics". The thing is i have to implement 7 types of users (5 types of students and 2 types of clerks) based on the number of books they can borrow and the amount of time they can keep the books until they have to return them. Those are the only 2 differences between the classes.

As a good rule of thumb, anywhere you see a noun in a project specification it's a good candidate for a class. If those nouns have relationships in the project spec, they probably aught to have one in your code too.

All of your people would fit in the category of a Userso perhaps this should be an interface they would all inherit. Down from this they appear to fit into two categories, Student and Staff perhaps these should also be abstract classes / interfaces. Then you have your 7 concrete classes. 2 inheriting Staff and 5 inheriting Student.

Classes are templates, and each template is used to construct an "instance of the class" or more specifically an "instance". One template is typically used to construct more than one class (although it is not necessary for a class to be used more than once, using it once (or not using it at all) is fine).

As you can see, there is going to be a lot of duplication between staff and students. getName(), getAge(), getPhoneNumber(), getAddress(), etc can easily be applied to both, which under this structure means that you would have to duplicate those methods for both Student and Staff.

This design also creates other issues, as it implies that a Staff member is not a Student, and a Student is not a Staff member. In the real world, sometimes the Staff enrolls for classes, and Students can take on teaching roles (think teacher's aide).

The Java Library plugin expands the capabilities of the Java Plugin (java) by providing specific knowledge about Java libraries.In particular, a Java library exposes an API to consumers (i.e., other projects using the Java or the Java Library plugin).All the source sets, tasks and configurations exposed by the Java plugin are implicitly available when using this plugin.

The plugin exposes two configurations that can be used to declare dependencies: api and implementation.The api configuration should be used to declare dependencies which are exported by the library API, whereas the implementation configuration should be used to declare dependencies which are internal to the component.

Dependencies appearing in the api configurations will be transitively exposed to consumers of the library, and as such will appear on the compile classpath of consumers. Dependencies found in the implementation configuration will, on the other hand, not be exposed to consumers, and therefore not leak into the consumers' compile classpath. This comes with several benefits:

If your build consumes a published module with POM metadata, the Java and Java Library plugins both honor api and implementation separation through the scopes used in the POM.Meaning that the compile classpath only includes Maven compile scoped dependencies, while the runtime classpath adds the Maven runtime scoped dependencies as well.

This often does not have an effect on modules published with Maven, where the POM that defines the project is directly published as metadata.There, the compile scope includes both dependencies that were required to compile the project (i.e. implementation dependencies) and dependencies required to compile against the published library (i.e. API dependencies).For most published libraries, this means that all dependencies belong to the compile scope.If you encounter such an issue with an existing library, you can consider a component metadata rule to fix the incorrect metadata in your build.However, as mentioned above, if the library is published with Gradle, the produced POM file only puts api dependencies into the compile scope and the remaining implementation dependencies into the runtime scope.

So when should you use the api configuration? An API dependency is one that contains at least one type that is exposed in the library binary interface, often referred to as its ABI (Application Binary Interface). This includes, but is not limited to:

types used in public method parameters, including generic parameter types (where public is something that is visible to compilers. I.e. , public, protected and package private members in the Java world)

Since Java 9, Java itself offers a module system that allows for strict encapsulation during compile and runtime.You can turn a Java library into a Java Module by creating a module-info.java file in the main/java source folder.

To tell the Java compiler that a Jar is a module, as opposed to a traditional Java library, Gradle needs to place it on the so called module path.It is an alternative to the classpath, which is the traditional way to tell the compiler about compiled dependencies.Gradle will automatically put a Jar of your dependencies on the module path, instead of the classpath, if these three things are true:

We are actually building a module (as opposed to a traditional library) which we expressed by adding the module-info.java file.(Another option is to add the Automatic-Module-Name Jar manifest attribute as described further down.)

There is a direct relationship to the dependencies you declare in the build file and the module dependencies you declare in the module-info.java file.Ideally the declarations should be in sync as seen in the following table.

The Java module system supports additional more fine granular encapsulation concepts than Gradle itself currently does.For example, you explicitly need to declare which packages are part of your API and which are only visible inside your module.Some of these capabilities might be added to Gradle itself in future versions.For now, please refer to documentation on the Java Module System to learn how to use these features in Java Modules.

You probably want to use external libraries, like OSS libraries from Maven Central, in your modular Java project.Some libraries, in their newer versions, are already full modules with a module descriptor.For example, com.google.code.gson:gson:2.8.9 that has the module name com.google.gson.

While a real module cannot directly depend on the unnamed module (only by adding command line flags), automatic modules can also see the unnamed module.Thus, if you cannot avoid to rely on a library without module information, you can wrap that library in an automatic module as part of your project.How you do that is described in the next section.

Another way to deal with non-modules is to enrich existing Jars with module descriptors yourself using artifact transforms.This sample contains a small buildSrc plugin registering such a transform which you may use and adjust to your needs.This can be interesting if you want to build a fully modular application and want the java runtime to treat everything as a real module.

In rare cases, you might want to disable the built-in Java Module support and define the module path by other means.To achieve this, you can disable the functionality to automatically put any Jar on the module path.Then Gradle puts Jars with module information on the classpath, even if you have a module-info.java in your source set.This corresponds to the behaviour of Gradle versions

If you can, you should always write complete module-info.java descriptors for your modules.Still, there are a few cases where you might consider to (initally) only provide a module name for an automatic module:

You are working on a library that is not a module but you want to make it usable as such in the next release.Adding an Automatic-Module-Name is a good first step (most popular OSS libraries on Maven central have done it by now).

A feature of the java-library plugin is that projects which consume the library only require the classes folder for compilation, instead of the full JAR.This enables lighter inter-project dependencies as resources processing (processResources task) and archive construction (jar task) are no longer executed when only Java code compilation is performed during development.

An indirect consequence is that up-to-date checking will require more memory, because Gradle will snapshot individual class files instead of a single jar.This may lead to increased memory consumption for large projects, with the benefit of having the compileJava task up-to-date in more cases (e.g. changing resources no longer changes the input for compileJava tasks of upstream projects)

Another side effect of the snapshotting of individual class files, only affecting Windows systems, is that the performance can significantly drop when processing a very large amount of class files on the compile classpath.This only concerns very large multi-projects where a lot of classes are present on the classpath by using many api dependencies.To mitigate this, you can set the org.gradle.java.compile-classpath-packaging system property to true to change the behavior of the Java Library plugin to use jars instead of class folders for everything on the compile classpath.Note, since this has other performance impacts and potentially side effects, by triggering all jar tasks at compile time, it is only recommended to activate this if you suffer from the described performance issue on Windows.

Aside from publishing a library to a component repository, you may sometimes need to package a library and its dependencies in a distribution deliverable.The Java Library Distribution Plugin is there to help you do just that.

library management system would be to create a separate class for handling the catalog of books, and another class for handling the individual books. This would allow for better organization and separation of concerns, as well as making the code more reusable. The Library class holds a list of all the books in the library and has methods for adding and removing books, as well as displaying all the books in the library. The LibraryManagementSystem class handles the user interface and communication between the Book and Library classes, using a Scanner object to get user input and controlling the overall flow of the program

c80f0f1006
Reply all
Reply to author
Forward
0 new messages