Skip to content

Instantly share code, notes, and snippets.

@ttrei
Last active February 1, 2019 08:35
Show Gist options
  • Save ttrei/9d34cc701648a76ab0a09273ceb5161b to your computer and use it in GitHub Desktop.
Save ttrei/9d34cc701648a76ab0a09273ceb5161b to your computer and use it in GitHub Desktop.
// CHALLENGE (work in pairs):
// Improve code snippets listed below –
//
// 1 - implement Xml class instead of XmlMarshaller
class XmlMarshaller {
byte[] marshallToXml(Invoice invoice) {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
JaxbMarshaller jaxbMarshaller = new JaxbMarshaller(Invoice.class);
jaxbMarshaller.marshallObject(invoice, outStream);
byte[] resultXml = outStream.toByteArray();
IOUtils.closeQuietly(outStream);
return resultXml;
}
}
byte[] t = new XmlMarchaller().marshallToXml(invoce);
//----
class Xml {
ByteArrayOutputStream os = new ByteArrayOutputStream();
Xml(Invoice invoice) {
new JaxbMarshaller(Invoice.class).marchallObject(invoice, this.os);
}
byte[] toByteArray() {
return this.os.toByteArray();
}
}
byte[] t = new Xml(invoice).toByteArray();
// 2 - refactor to eliminate all null checks and branching
class AmazonS3File {
private final String path;
private Optional<Metadata> metadata;
void attach(Metadata metadata) {
this.metadata = Optional.of(metadata);
}
//@Nullable
Optional<Metadata> getMetadata() {
return metadata;
}
}
class AmazonS3Bucket {
void upload(AmazonS3File file) {
//… upload ...
file
.flatMap(File::getMetadata)
.map(it -> uploadMetadata(it));
//if (file.getMetadata() != null) {
// uploadMetadata(file.getMetadata());
//}
}
private void uploadMetadata(Metadata metadata) {
....
}
}
// 4 - fix conflicting method names. No getters & setters allowed!
user.ban() // returns user's ban and the corresponding information (if any)
user.ban() // bans a user
//----
user.banDetails() // returns user's ban and the corresponding information (if any)
user.ban() // bans a user
// user.activeBan() // word-play
// user.putABan()
// 5 – get rid of procedural design
interface MoneyFormatter {
String format(Money money);
}
//----
class Money {
String asString();
}
// ---
class ISO111MFOrmattedMoney implements FormattedMoney { ... }
interface FormattedMoney {
FormattedMoney(Money money) {
}
string toString() {
}
}
//
class PrettyMoney {
PrettyMoney(Money money) {
}
string toString() {
}
}
// 6 - implement "fullName" method, so that it returned "firstName lastName" if nickname is missing
// or "firstName <nickname> lastName" if nickname is present.
// for example – "Robert Martin" or "Robert <Uncle Bob> Martin"
// don't optimize prematurely (e.g. prefer simple String concatenation over StringBuilder).
class User {
private final Optional<String> nickName;
private final String firstName;
private final String lastName;
String fullName() {
return nickname
.map(it -> firstName + " <" + it + "> " + lastName)
.orElseGet(() -> firstName + " " + lastName);
//.orElse(firstName + " " + lastName) - will be executed regardless
// 9+ jvm hotspot automatically converts string concatenation into string builder
}
}
// 7
// no setters please
class User {
private final Permissions permissions;
void setPermissions(Permissions permissions) {
this.permissions = permissions
}
}
class BankAccount {
enum Status {
CLOSED, OPEN
}
private final Status status;
void setStatus(Status status) {
this.status = status;
}
}
// ----
class User {
private final Permissions permissions;
void allowAccess() {
this.permissions =
}
void denyAccess() {
this.permissions =
}
}
class BankAccount {
enum Status {
CLOSED, OPEN
}
private Status status;
void open() {this.status = Status.OPEN}
void close() {this.status = Status.CLOSED}
}
// 8
// calling a logic (such as remote system call) in a constructor is a bad idea. Do you know how to fix that?
class SecurePassword {
private final String rawPassword;
private SecurePassword(Vault vault) {
this.rawPassword = vault.verySecurePassword();
}
public String raw() {
return rawPassword;
}
}
//-----
class SecurePassword {
private final Optional<String> rawPassword;
private final Vault vault;
private SecurePassword(Vault vault) {
this.vault = vault;
}
public String raw() {
if (!rawPassword.ifPresent()) {
this.rawPassword = vault.verySecurePassword();
}
return rawPassword;
}
}
//
class SecurePassword {
/*
@FunctionalInterface
interface Supplier<T> {
T get() {}
}*/
private final Supplier<String> rawPassword;
public SecurePassword(Vault vault) {
// .memoize() - requires GUAVA
this.rawPassword = memoize(vault::verySecurePassword);
}
public String raw(){
return rawPassword.get();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment