As we start our learning for our final project in our class, we have started to learn about and work with RESTful API architecture style (REST API), so I have started some research and done further learning myself. I found a great article from by Margaret Rouse with an wide view of the application program interface, called RESTful API. She breaks down what it is, how it works, its uses, its constraints, challenges, and some background information. REST uses the HTTP requests of GET, PUT, POST, and DELETE for data use and access. This API is based on representational state transfer, which is what the acronym stands for. It works by, “[Breaking] down a transaction to create a series of small modules. Each module addresses an underlying part of the transaction.” Commands are used to obtain resources, and resource’s states is called a resource representation. As previously mentioned, the commands are: GET to retrieve a resource, PUT to modify/updated a resource, POST to create a resource, and DELETE to remove a resource. The idea is for users to access networked components with stateless calls, no information being retained by the REST services. This statelessness makes REST “useful in cloud applications.” They are scalable and can be “redeployed if something fails.” It is very useful for efficient internet usage and is very compatible for distributed environments, and is used by the likes of Amazon, Google, LinkedIn, and Twitter. With cloud and microservices growing in popularity and usage, REST is sure to grow alongside. REST adheres strictly to 6 key concepts. There must be a uniform interface under a single URL. It must be client-server based, dividing request-gathering concerns on the client and data access, workload management, and security on the server. There must be stateless operations, as mentioned previously. Any state information must be managed on the client. Caching is essential for resources unless “explicitly indicated that caching is not possible. It must be a layered system, like a hierarchy to the architecture. There must be code on demand, meaning that “a server will send back static representations of resources,” or “when necessary, servers can send executable code to the client.” Sticking to these requirements can be difficult, which presents the challenges of endpoint consistency, response time and data size, defining paths and locations, security, authentication, request scope, testing, and error handling. Since REST is useful for the aforementioned reasons, this is worthwhile and understandable though. I expect to use this information in my final project, which should be dealing in a REST API, so this will be very useful to me in the near future. It is very interesting and exciting, and is growing to the top of the computer science world.
In keeping with my recent learning with java design patterns, I have been learning about the Factory Design Pattern. It is defined as a creational pattern by the Gang of Four and is very widely used because of the plethora of applications that it has. This seemed to be one of the best design patterns to learn as I saw a great many recommendations to do so in my research on design patterns. In the Factory Method Pattern article from Java T Point, the design pattern is made by, “[defining] an interface or abstract class for creating an object but [letting] the subclasses decide which class to instantiate.” In other words, if the client requires multiple similar behaviors, the Factory Design Pattern is used to choose the required subclass instance to complete the required behavior. The article outlines the key advantages to this design pattern, including the promotion of “loose-coupling” because of the lack of application specific classes into the code. It then gives a couple of examples for usage including a class not knowing what subclasses will be required. There is then a simple UML diagram which shows a small example of how an electricity bill may be calculated using the Factory Design Pattern. This example is then expanded upon. First, an abstract Plan class is created. It contains an abstract getRate method and a concrete calculateBill method. The subclasses show the real usefulness of the design pattern. There are 3 subclasses: DomesticPlan (with a rate of 3.50), CommercialPlan (with a rate of 7.50), and InstitutionalPlan (with a rate of 5.50). Each class implements the getRate method, which sets the Plan class’s rate variable to their respective rates. From here, a GetPlanFactory class is created which uses the Plan class and its subclasses to return a Plan object. The one method here is getPlan, which takes a string variable and has a set of if statements, each of which returns a different Plan subclass object depending on the string. Finally, the GenerateBill class is the one which the client interacts with. It asks the client the name of the plan needed, which the PlanFactory class uses to return an object of the one of the Plan subclasses. Then, units of electricity are taken from the client. The Plan subclass object then calls getRate to get the rate associated with the plan, and then calculateBill to tell the client the total charge for electricity usage. Although the explanation seems complicated, it is quite simple and clean in implementation, and extremely useful when one does not know which of a given set of behaviors will be required. I expect I can use this design pattern quite frequently in my personal, school-related, and professional coding.
In keeping with my recent learning about Java Design Patterns, as outlined by the Gang of Four, I have recently been doing research on the State Design Pattern. I came across an extremely useful article which details the Design Pattern logic, implementation, upsides and downsides, as well as giving an overall evaluation. The article is titled “State Design Pattern in Java,” by Denis Szczukocki, and starts by explaining that the main usage for the State pattern is “to allow the object for changing its behavior without changing its class.” It is also cleaner than a project cluttered with if/else statements for controlling object behavior. The basis is that an object who’s behavior is dependent on a specific state can easily change states and therefore change behaviors without the creation of a new object and the classes responsible for this behavior will be “tightly coupled.” Within the pattern, there will be 2 essential classes and a number of extra classes dependent on the number of states required. The first is the context class. The context class delegates object behavior to the other class, the state class, but the context class is the one used by the client. The state class is usually an interface, with the concrete state classes implementing this interface and dictating behavior. The article gives the example of a package with 3 states: ordered, delivered, and received. There is a package class, which is the context class, and contains methods to move to the next/previous states and print the status as well. When an instance of the package class is created, really what happens is that an instance of the first state (ordered is created). When ready, the package object can move to the delivered state, and then the received state, all of which have different behaviors. The three behaviors in the PackageState interface common to all concrete states are next, previous, and printStatus, each which has a different behavior depending on the concrete class of the package. The article then notes that a possible downside to the State design pattern is that, “the state becomes hardcoded, which is a bad practice in general.” This taught me how to use the State Design Pattern and why it is good practice. I plan to use this in future projects when I can in order to practice, as well as to implement good project design practice. It is understandable and not terribly difficult to implement, so I know this can help me in my future work.
As I progress more in my CS studies, I’m starting to move beyond learning how to write the code for a project to how the project should be designed overall. In fact, this is one of the main purposes of two of my current CS classes. This has lead me to learning about TDD, or Test Driven Development. I’ve come across a fantastic article by Andrea Koutifaris which outlines the concept well called Test Driven Development: what it is, and what it is not.
In this article, I’ve learned the purpose of writing test driven code and what the plan for doing it should be. In TDD, tests come first in the process while writing production code comes second. This is in order to almost put oneself in a user’s shoes. If I myself in the user, what do I want my code to do? This is where the tests come in. Once the goals are clear and defined, the production code can be written.
The rules for TDD can be broken down to two essential parts:
- “Write only enough of a unit test to fail”
- “Write only enough production code to make the failing unit test pass”
Tests must be written to be very specific and achieve the ultimate application goals. Analysis of your tests can help you determine a method to writing your production code. They often not only outline what need to be achieved, but how it needs to be achieved.
The next part of TDD would be writing production code. As outlined before, the second essential rule of TDD is to “Write only enough production code to make the failing test unit pass.” Had production code been written first, output may not match user goals and unnecessary code may be written, which comes with its own set of problems. The focus is on writing clean code and limiting the amount which you write.
The last part of TDD would be the “refractor phase.” This is where code can be changed to be better, but what is stressed here is removing all duplicate code and consolidating.
The result of TDD should be efficient, clean code which serves its purpose. Although it can seem long-winded and like extra work, it’s mostly just inverting the process which we usually work by, so once the process is learned and practiced, it can help with writing better code more coherently and more focused on user goals, which is the ultimate goal as a programmer.