The title might not be very clear but i could not figure out a better one. Here is the problem. I have a Scope interface which gives all the pages where a QueryEngine should query in.
interface Scope{
Set<Page> getPages();
}
interface QueryEngine{
void query(Scope scope){
queryIn(scope.getPages());
}
}
There is another type of scope which says query all the pages other than the ones it provides.
I was trying to model this behavior.
interface ExcludeScope extends Scope{
}
In which case i have to do something like below in QueryEngine
interface QueryEngine{
void query(Scope scope){
if(scope instanceof ExcludeScope){
queryInPagesOtherThan(scope.getPages());
}else{
queryIn(scope.getPages());
}
}
}
Or should it be something which is driven by a boolean
interface Scope{
Set<Page> getPages();
boolean shouldExclude();
}
I feel both the above approaches would lead to if, else conditions in the QueryEngine
which means that it is not closed for modifications.
How to design such a behaviour? What should be the approach one should follow while tackling any design problem? Should we start by checking whether SOLID principles were followed? Should we look to classify the problem under a design pattern thus arrive at a solution?
One possibility is to perform an inversion of control: The QueryEngine asks a Scope whether to process a page or not and the Scope answers independently true or false, similar to
interface Scope {
boolean process(Page page);
}
interface QueryEngine {
void query(Scope scope, Set<Page> pages) {
Set<Pages> pagesToProcess = new HashSet<Page>();
for (Page page : pages) {
if (scope.process(page)) {
pagesToProcess.add(page);
}
}
queryIn(pagesToProcess);
}
}
class IncludeScope implements Scope {
private static final Set<Page> INCLUDING_PAGES = ...
public boolean process(Page page) {
return INCLUDING_PAGES.contains(page);
}
}
class ExcludeScope implements Scope {
private static final Set<Page> EXCLUDING_PAGES = ...
public boolean process(Page page) {
return !EXCLUDING_PAGES.contains(page);
}
}
In my opinion the root of your problem is in this sentence:
There is another type of scope which says query all the pages other than the ones it provides".
Scope has nothing to do with querying, it should only represent a subset of all elements. You seem to want to perform a query in a different way, so I would suggest to go for a new method in the QueryEngine:
interface QueryEngine{
void query(Scope scope){
...
}
void queryComplement(Scope scope) {
...
}
}
Related
My question is about what should be the most OOP solution and the right design pattern for my situation. We have a user entity and multiple account entities belong to the user. Account entities can have multiple states and we can execute multiple operations on accounts. The outcome of these operations is based on the account entity's state.
I have the following code which is based mostly on switch (sometimes it looks like a few "if"). I would like to change it but cannot find the right design pattern.
enum Status {
ACTIVE, INACTIVE, DELETED;
}
#Entity
class Account {
private long id;
private long userid;
private Status status;
//...
}
class AccountService{
Account delete(long id) {
//...
if (accountInfo.getSatus() == DELETED) {
throw new IllegalOperationException();
}
if (accountInfo.getStatus() == ACTIVE || accountInfo.getStatus()) {
accountInfo.setStatus(DELETED);
accountInfoRepository.save(accountInfo);
}
}
Account create (Account account) {
// various operations based on state
}
}
I really want to refactor these codes, I fear that as soon as our service grows it will contain more "magic" and will be hard to maintain. And if we would like to introduce a new state it will be nearly impossible.
My junior mind thought that I should have state objects which would implement all the operations, in pseudo-code style:
class AccountService {
private StateFactory stateFactory;
private AccountRepository accountRepository;
Account delete(long id) {
final Optional<Account> account = accountRepository.findById(id);
Account deletedAccount = account.map(stateFactory::getByState)
.map(accountState -> accountState.delete(account))
.orElseThrow(() -> new IllegalOperationException());
return accountRepository.save(deletedAccount);
}
Account create (Account account) {
// various operation based on state
}
}
and:
class ActiveState extends AccountState {
#Override
public Account delete(Account account) {
//implementation
}
#Override
public Account activate(AccountInfo) {
// implementation
}
}
and:
interface AccountState {
Account activate(AccountInfo);
Account delete(AccountInfo);
}
I know there must be a better implementation for this problem. Which other design patterns are suitable for this setup?
UPDATE
I have found a few interesting articles to read in the topic:
How to implement a FSM - Finite State Machine in Java
When you have more complex state handling
If I understood question correctly, then it is necessary to apply some action by its state.
If it is true, then we can use Factory pattern to get desired object which can execute some action. Mapping between state and action can be putted into HashTable.
So let's see an example of code. I will write via C#, but this code can be easily translated to Java because languages have many syntax similarities.
So we will have enum of statuses:
public enum Status
{
Active,
Deleted,
Foo
}
and states of AccountState
public abstract class AccountState
{
public abstract void ExecSomeLogic();
}
public class ActiveState : AccountState // "extends" instead of ":" in Java
{
public override void ExecSomeLogic()
{
}
}
public class DeletedState : AccountState // "extends" instead of ":" in Java
{
public override void ExecSomeLogic()
{
}
}
public class FooState : AccountState // "extends" instead of ":" in Java
{
public override void ExecSomeLogic()
{
}
}
Then we need mapper class of Status to their AccountState:
public class StatusToAccountState
{
public Dictionary<Status, AccountState> AccountStateByStatus { get; set; } =
new Dictionary<Status, AccountState>() // HashMap in Java
{
{ Status.Active, new ActiveState() },
{ Status.Deleted, new DeletedState() },
{ Status.Foo, new FooState() },
};
}
And then in your service you can use it like this:
void Delete(long id, Status status)
{
StatusToAccountState statusToAccountState = new StatusToAccountState();
AccountState accountState = statusToAccountState.AccountStateByStatus[status];
accountState.ExecSomeLogic();
}
If there are many logic to figure out what Status of object is, then you can create some class which will have just one responisibility of figuring out what state of object is:
public class StatusManager
{
public Status Get()
{
return Status.Active; // or something another based on logic
}
}
After doing this, your classes will correspond to the single responsibility principle of SOLID. Read more about single responsibility principle of SOLID here
Too many switch-/if-Statements indicate the code smell "Tool Abusers" (see M. Fowler "Refactoring"). Use the polymorphism mechanics to solve this.
https://refactoring.guru/smells/switch-statements
[See below for updates]
I am having a hard time defining a pattern. My colleague says it's adaptor pattern. I'm not sure. We're stuck mainly because we want to correctly name our components.
Question: Is it adapter pattern? If not what is it? If it is something else, is this the best way to implement the idea?
To put it in summary, it is a main component(is this the adapter?) that shares an interfaces with sub-components (are these providers?). The main components decides/orchestrates which of the sub-components are called. The main component behaves as some sort of "wrapper" to call one of the others that have the same interface. The instances of which are injected through the constructor.
Assumptions:
For simplicity, we will ignore DR/IoC for now, but we understand and apply the pattern/principle.
The code is not the best implemented form...feel free to suggest.
My use of the words main/sub does not infer some kind of inheritence...just bad naming on my part, if confusing.
It's language-agnostic, because I love contributions from C# and Java guys, and the knowledge they share.
I am using a Social Networking scenario where a main component gets stats on a hastag and instantiates the appropriate Social Sub Component (
There is a Social Component interface:
ISocialComponent
{
SomeStatsObject GetStats(string hashTag);
}
Social Sub-Components implement ISocialComponent Interface
Twitter Sub-Component
public class TwitterSubComponent : ISocialComponent
{
public SomeStatsObject GetStats(string hashTag)
{
return SomeMethodThatReturnsStatsObject(hashTag);
}
private SomeMethodThatReturnsStatsObject(string hashTag)
{
//... Twitter-specific code goes here
}
}
Facebook Sub-Component
public class FacebookSubComponent : ISocialComponent
{
public SomeStatsObject GetStats(string hashTag)
{
return SomeMethodThatReturnsStatsObject(hashTag);
}
private SomeMethodThatReturnsStatsObject(string hashTag)
{
//... Facebook-specific code goes here
}
}
Instagram Sub-Component
public class InstagramSubComponent : ISocialComponent
{
public SomeStatsObject GetStats(string hashTag)
{
return SomeMethodThatReturnsStatsObject(hasTag);
}
private SomeMethodThatReturnsStatsObject(string hashTag)
{
//... Instagram-specific code goes here
}
}
Main Component
There is a main social component object that calls any one of the Sub-Components (defined below) that implement the shared ISocialComponent interface
public class MainSocialComponent : ISocialComponent
{
//this is an enum
private RequestedNetwork _requestedNetwork{ get; set;}
//the SocialComponent instance is injected outside of this class
private readonly ISocialComponent _socialComponent;
public MainSocialComponent(ISocialComponent socialComponent)
{
_socialComponent = socialComponent;
}
public SomeStatsObject GetStats(string hashTag)
{
return _socialComponent.GetStats(hashTag)
/**** original code, kept for historical purposes****
switch(_requestedNetwork)
{
case RequestedNetwork.Twitter:
var twit = new TwitterSubComponent();
return twit.GetStats(hashTag)
break;
case RequestedNetwork.Facebook:
var fb = new FacebookSubComponent();
return fb.GetStats(hashTag)
break;
case RequestedNetwork.Instagram:
var in = new InstagramSubComponent();
return in.GetStats(hashTag)
break;
default:
throw new Exception("Undefined Social Network");
break;
}*/
}
}
Updates:
I see why some say it is Factory pattern because it is creating objects. I had mentioned that we use an IoC container and DR. It was my mistake to exclude that. I have refactored the code
As others have mentioned, this is part of the Factory/Service pattern which is pretty popular for Dependency Injection and Inversion of Control.
Right now though there is no reason to declare your sub components as non static, since you aren't saving your instances to anything.
So it seems to me unless you have missing code where you add the components to a list or something, you could just do this:
public static class InstagramSubComponent : ISocialComponent
{
public static SomeStatsObject GetStats(string hashTag)
{
return stuff;
}
}
public class MainSocialComponent : ISocialComponent
{
//this is an enum
private RequestedNetwork _requestedNetwork{ get; set;}
private static var Mappings = new Dictionary<string, Func<SomeStatsObject>> {
{ "Twitter", TwitterSubComponent.GetStats },
{ "Facebook", FacebookSubComponent.GetStats },
{ "Instagram", InstagramSubComponent.GetStats }
}
public SomeStatsObject GetStats(string hashTag)
{
return Mappings[hashTag].invoke();
}
}
}
Now if you are doing stuff like actually saving your instances of sub components to a list for later or whatever, then that changes everything. But I am not seeing that so there's no reason not to just make it all static if these methods are simple.
If they are very complex then you'll want to use dependency injection so you can unit test everything proper.
I believe you can extract creation of SubComponent into a Factory and pass this Factory to MainSocialComponent. Inside of the GetStats method, you will call _factory.Create(hashTag); and than call GetStats on the returned object.
This way you'll have factory pattern.
This is definitely not an adapter pattern.
An adapter pattern does the following in most cases :
• Works as a bridge between two incompatible interfaces.
• Allows classes with incompatible interfaces work together
Your case is more like a Factory pattern. You use high level abstraction and return the type of interface/component whenever you need to.
In one of my projects I need to compare the URI with several regex patterns(15+ regex patterns). Currently I have used a if ladder to see if either one of them gets matched and there onward the logical part of the code is executed.
Glimpse of the code now:
if (uri.matches(Constants.GET_ALL_APIS_STORE_REGEX)) {
long lastUpdatedTime = InBoundETagManager.apisGet(null, null, tenantDomain, null);
String eTag = ETagGenerator.getETag(lastUpdatedTime);
if (eTag.equals(ifNoneMatch)) {
message.getExchange().put("ETag", eTag);
generate304NotModifiedResponse(message);
}
message.getExchange().put("ETag", eTag);
}
else if (uri.matches(Constants.GET_API_FOR_ID_REGEX)) { // /apis/{apiId}
apiId = UUIDList.get(0);
String requestedTenantDomain = RestApiUtil.getRequestedTenantDomain(tenantDomain);
long lastUpdatedTime = InBoundETagManager.apisApiIdGet(apiId, requestedTenantDomain, uri);
String eTag = ETagGenerator.getETag(lastUpdatedTime);
handleInterceptorResponse(message, ifNoneMatch, eTag);
}
else if (uri.matches(Constants.GET_SWAGGER_FOR_API_ID_REGEX)) { // /apis/{apiId}/swagger
apiId = UUIDList.get(0);
long lastUpdatedTime = InBoundETagManager.apisApiIdSwaggerGet(apiId, tenantDomain);
String eTag = ETagGenerator.getETag(lastUpdatedTime);
if (lastUpdatedTime == 0L) {
log.info("No last updated time available for the desired API swagger json file");
}
handleInterceptorResponse(message, ifNoneMatch, eTag);
}
Can someone please introduce me with a more neat and clever way of doing this regex matching thing?
One url-type(regex) = one handler = one class. This way would be much easier to read and support especially if you have 15 regex checks.
interface URLHandler {
void handle();
boolean isSupported(String url);
}
class GetAllApisStoreHandler implements URLHandler{
private static final Pattern GET_ALL_API_STORE_PATTERN = Pattern.compile(GET_ALL_APIS_STORE_REGEX);
public boolean isSupported(String url) {
return GET_ALL_API_STORE_PATTERN.matcher(url).matches();
}
public void handle(...) {
...
}
}
class GetApiIdHandler implements URLHandler{
private static final Pattern GET_API_ID_REGEX = Pattern.compile(GET_API_ID_REGEX);
public boolean isSupported(String url) {
return GET_API_ID_PATTERN.matcher(url).matches();
}
public void handle(...) {
...
}
}
class GetApiIdHandler implements URLHandler{
private static final Pattern GET_SWAGGER_FORAPI_ID_PATTERN = Pattern.compile(GET_SWAGGER_FOR_API_ID_REGEX);
public boolean isSupported(String url) {
return GET_SWAGGER_FORAPI_ID_PATTERN.matcher(url).matches();
}
public void handle(...) {
...
}
}
class Main {
private List<URLHandler> urlHandlers;
public void method(){
...
for (URLHandler handler : urlHandlers) {
if(handler.isSupported(url)) {
handler.handle(arg1, arg2, arg3, ...);
}
}
...
}
}
Using multiple classes as #KonstantinLabun proposed is probably the way to go(*), but it shouldn't lead to much code duplication. So use an abstract class instead of (or in addition to an interface). Or (mis)use default methods.
abstract class URLHandler {
abstract void handle();
abstract Pattern urlPattern():
final boolean isSupported(String url) {
return urlPattern().matcher(url).matches();
}
}
class GetAllApisStoreHandler extends URLHandler{
private static final Pattern URL_PATTERN =
Pattern.compile(Constants.GET_ALL_APIS_STORE_REGEX);
Pattern urlPattern() {
return URL_PATTERN;
}
public void handle(...) {
...
}
}
There's no need to invent names for the PATTERN as its scope identified it already. The static field exists only as an optimization, so that the Pattern don't get compiled for each match.
(*) There's nothing wrong with a single class, as long as it's concise (I like spaghetti except in code) and doesn't leak implementation details. There's nothing wrong with multiple classes (except maybe on Android as 50 kB per class might matter) as long as they don't lead to code bloat. An enum is sometimes a good solution, too.
Explanation of abstract class vs. interface
An interface forces you to implement its methods(**), which may quickly lead to duplication. It's advantage is multiple inheritance and some conceptual purity.
An abstract class allows you to gather the common parts. But there's no dilemma, you can do both, see e.g., interface List and abstract class AbstractList.
(**) Since Java 8, an interface can have default methods, so this is no more true. Assuming you want to use them for this purpose. It can't declare any state, but it can access the state of the object. For example, my above URLHandler could be such an interface. There are still disadvantages, e.g., methods must be public and mustn't be final.
I want to refactor an existing class of almost 5000 lines but I'm having difficulty with the constructor. Right now it's something like the following(methods here are in reality 10-30 blocks of code )
public MyClass( MyObject o ) {
if ( o.name.equalsIgnoreCase("a") ) {
doSomething()
} else {
doSomethingElse()
}
commonCode()
if (o.name.equalsIgnoreCase("a") ) {
doSecondThing()
} else {
doOtherSecondThing() //almost identical to doSecondThing but with some extra steps that absolutely have to be done in this sequence
}
// more of the same
}
I considered using inheritance and breaking things up into functions that would be overridden where necessary but that feels messy to me. Is there a pattern that fits this use case? Incidentally any advice on refactoring legacy code would be more than welcome.
You are exactly right. Refactoring like you described is called
Replace Conditional with Polymorphism.
Also you can look through on Chain-of-responsibility, Command or Strategy design patterns.
If every object follows the following pattern:
if(conditionA)
DoA();
else
DoElse();
Common();
if(conditionA2)
DoA2();
else if(conditionB2)
DoB2();
else
DoElse2();
Common2();
I'd advice you to have a common class that gathers handlers with conditions. This is roughly what I mean (Pseudo-code not java):
public interface IConditionalHandler
{
bool Condition();
void Action();
}
public class ActionHandler
{
private List<IConditionalHandler> m_FirstHandlers;
private List<IConditionalHandler> m_SecondHandlers; //Or possibly use a list of lists
public ActionHandler()
{
m_FirstHandlers = new ArrayList<>();
m_FirstHandlers.add(new HandlerA1());
m_FirstHandlers.add(new HandlerB1());
m_SecondHandlers = new ArrayList<>();
m_SecondHandlers.add(new HandlerA1());
m_SecondHandlers.add(new HandlerB1());
}
void DoStuff()
{
for(IConditionHandler handler : m_FirstHandlers)
{
if(handler.Condition())
{
handler.Action();
break;
}
}
CommonA();
for(IConditionHandler handler : m_SecondHandlers)
{
if(handler.Condition())
{
handler.Action();
break;
}
}
}
}
If you have lots of segment, a list of lists can include your common code as an exit-handler and contain all of the logic. You delegate the logic out to implementing classes, and shorten the actual code in your class.
However, as far as efficiency goes you are going to kill both the instruction and data cache. If this isn't what you're looking for, then more than likely this is: Chain-of-Responsibility Pattern - Wikipedia
I am going to develop a web crawler using java to capture hotel room prices from hotel websites.
In this case I want to capture room price with the room type and the meal type, so my algorithm should be intelligent to handle that.
For example:
Room type: Deluxe
Meal type: HalfBoad
price : $20.00
The main problem is room prices can be in different ways in different hotel sites. So my algorithm should be independent from hotel sites.
I am plan to use above room types and meal types as a fuzzy sets and compare the words in webpage with above fuzzy sets using a suitable membership function.
Anyone experienced with this? or have an idea for my problem?
There are two ways to approach this problem:
You can customize your crawler to understand the formats used by different Websites; or
You can come up with a general ("fuzzy") solution.
(1) will, by far, be the easiest. Ideally you want to create some tools that make this easier so you can create a filter for any new site in minimal time. IMHO your time will be best spent with this approach.
(2) has lots of problems. Firstly it will be unreliable. You will come across formats you don't understand or (worse) get wrong. Second, it will require a substantial amount of development to get something working. This is the sort of thing you use when you're dealing with thousands or millions of sites.
With hundreds of sites you will get better and more predictable results with (1).
As with all problems, design can let you deliver value adapt to situations you haven't considered much more quickly than the general solution.
Start by writing something that parses the data from one provider - the one with the simplest format to handle. Find a way to adapt that handler into your crawler. Be sure to encapsulate construction - you should always do this anyway...
public class RoomTypeExtractor
{
private RoomTypeExtractor() { }
public static RoomTypeExtractor GetInstance()
{
return new RoomTypeExtractor();
}
public string GetRoomType(string content)
{
// BEHAVIOR #1
}
}
The GetInstance() ,ethod lets you promote to a Strategy pattern for practically free.
Then add your second provider type. Say, for instance, that you have a slightly more complex data format which is a little more prevalent than the first format. Start by refactoring what was your concrete room type extractor class into an abstraction with a single variation behind it and have the GetInstance() method return an instance of the concrete type:
public abstract class RoomTypeExtractor
{
public static RoomTypeExtractor GetInstance()
{
return SimpleRoomTypeExtractor.GetInstance();
}
public abstract string GetRoomType(string content);
}
public final class SimpleRoomTypeExtractor extends RoomTypeExtractor
{
private SimpleRoomTypeExtractor() { }
public static SimpleRoomTypeExtractor GetInstance()
{
return new SimpleRoomTypeExtractor();
}
public string GetRoomType(string content)
{
// BEHAVIOR #1
}
}
Create another variation that implements the Null Object pattern...
public class NullRoomTypeExtractor extends RoomTypeExtractor
{
private NullRoomTypeExtractor() { }
public static NullRoomTypeExtractor GetInstance()
{
return new NullRoomTypeExtractor();
}
public string GetRoomType(string content)
{
// whatever "no content" behavior you want... I chose returning null
return null;
}
}
Add a base class that will make it easier to work with the Chain of Responsibility pattern that is in this problem:
public abstract class ChainLinkRoomTypeExtractor extends RoomTypeExtractor
{
private final RoomTypeExtractor next_;
protected ChainLinkRoomTypeExtractor(RoomTypeExtractor next)
{
next_ = next;
}
public final string GetRoomType(string content)
{
if (CanHandleContent(content))
{
return GetRoomTypeFromUnderstoodFormat(content);
}
else
{
return next_.GetRoomType(content);
}
}
protected abstract bool CanHandleContent(string content);
protected abstract string GetRoomTypeFromUnderstoodFormat(string content);
}
Now, refactor the original implementation to have a base class that joins it into a Chain of Responsibility...
public final class SimpleRoomTypeExtractor extends ChainLinkRoomTypeExtractor
{
private SimpleRoomTypeExtractor(RoomTypeExtractor next)
{
super(next);
}
public static SimpleRoomTypeExtractor GetInstance(RoomTypeExtractor next)
{
return new SimpleRoomTypeExtractor(next);
}
protected string CanHandleContent(string content)
{
// return whether or not content contains the right format
}
protected string GetRoomTypeFromUnderstoodFormat(string content)
{
// BEHAVIOR #1
}
}
Be sure to update RoomTypeExtractor.GetInstance():
public static RoomTypeExtractor GetInstance()
{
RoomTypeExtractor extractor = NullRoomTypeExtractor.GetInstance();
extractor = SimpleRoomTypeExtractor.GetInstance(extractor);
return extractor;
}
Once that's done, create a new link for the Chain of Responsibility...
public final class MoreComplexRoomTypeExtractor extends ChainLinkRoomTypeExtractor
{
private MoreComplexRoomTypeExtractor(RoomTypeExtractor next)
{
super(next);
}
public static MoreComplexRoomTypeExtractor GetInstance(RoomTypeExtractor next)
{
return new MoreComplexRoomTypeExtractor(next);
}
protected string CanHandleContent(string content)
{
// Check for presence of format #2
}
protected string GetRoomTypeFromUnderstoodFormat(string content)
{
// BEHAVIOR #2
}
}
Finally, add the new link to the chain, if this is a more common format, you might want to give it higher priority by putting it higher in the chain (the real forces that govern the order of the chain will become apparent when you do this):
public static RoomTypeExtractor GetInstance()
{
RoomTypeExtractor extractor = NullRoomTypeExtractor.GetInstance();
extractor = SimpleRoomTypeExtractor.GetInstance(extractor);
extractor = MoreComplexRoomTypeExtractor.GetInstance(extractor);
return extractor;
}
As time passes, you may want to add ways to dynamically add new links to the Chain of Responsibility, as pointed out by Cletus, but the fundamental principle here is Emergent Design. Start with high quality. Keep quality high. Drive with tests. Do those three things and you will be able to use the fuzzy logic engine between your ears to overcome almost any problem...
EDIT
Translated to Java. Hope I did that right; I'm a little rusty.